commit e2e53267c646144564d1832ea29758d771bfb60d Author: IMback Date: Sun May 14 23:29:55 2017 +0200 Initial commit diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..734a107 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,50 @@ +## A simple CMake file to compile an Arduino project. +## Adjust the settings according to your board. +## The settings here work for the Arduino Uno, Rev. 3. + +# Project name +project(cncextension) + +# CMake version +cmake_minimum_required(VERSION 2.6) + +# Options +# Adjust to your board +set(MCU "m328p" CACHE STRING "Processor Type") +set(CPU_SPEED "16000000" CACHE STRING "Speed of the CPU") +set(PORT "/dev/ttyUSB0" CACHE STRING "USB Port") +set(PORT_SPEED "57600" CACHE STRING "Serial Port Speed") +set(PROGRAMMER "stk500v1" CACHE STRING "Programmer Type") +set(COMPILE_FLAGS "" CACHE STRING "Additional Compiler Flags") + +# Set own source files +# Simply list all your C / C++ source (not header!) files here +set(SRC_FILES main.cpp serial.cpp WirelessRelay.cpp pwm.cpp encoder.cpp) + +# Compiler suite specification +set(CMAKE_C_COMPILER /usr/bin/avr-gcc) +set(CMAKE_CXX_COMPILER /usr/bin/avr-g++) +set(CMAKE_OBJCOPY /usr/bin/avr-objcopy) +set(CMAKE_OBJDUMP /usr/bin/avr-objdump) +set(CMAKE_RANLIB /usr/bin/avr-ranlib) +set(CMAKE_LINKER /usr/bin/avr-ld) + +# Compiler flags +add_definitions(-mmcu=${MCU} -DF_CPU=${CPU_SPEED}) +add_definitions(-c -g -Os -Wall -std=c++11 ) +add_definitions(-fno-exceptions -ffunction-sections -fdata-sections) + +# Linker flags +set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # remove -rdynamic for C +set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") # remove -rdynamic for CXX +set(CMAKE_EXE_LINKER_FLAGS "-Os -Wl,--gc-sections -mmcu=${MCU}") + +add_executable(${PROJECT_NAME} ${ARDUINO_CORE_SRC} ${SRC_FILES}) + +find_program(AR_AVRDUDE NAMES avrdude PATHS /usr/bin NO_DEFAULT_PATH) + +add_custom_target(download + COMMAND ${CMAKE_OBJCOPY} -j .text -j .data -O ihex ${PROJECT_NAME} ${PROJECT_NAME}.hex + COMMAND ${AR_AVRDUDE} -v -p ${MCU} -c ${PROGRAMMER} -P /dev/ttyUSB0 -b 57600 -D -U flash:w:${PROJECT_NAME}.hex + DEPENDS ${PROJECT_NAME} + ) diff --git a/WirelessRelay.cpp b/WirelessRelay.cpp new file mode 100644 index 0000000..6ffae4d --- /dev/null +++ b/WirelessRelay.cpp @@ -0,0 +1,75 @@ +#include"WirelessRelay.h" + + +void WirelessRelay::sendId() +{ + writePin(_port,_pin,true); + _delay_us(SMALL_TIME); + writePin(_port,_pin,false); + _delay_us(LARGE_TIME); + + for(short i = 0; i<10; i++) + { + sendBit( _id & 1 << (15 - i) ? true : false ); + } +} + +void WirelessRelay::sendBit(const bool in) +{ + switch(in) + { + case true: + //Der Code fuer '0' + writePin(_port,_pin,true); + _delay_us(SMALL_TIME); + writePin(_port,_pin,false); + _delay_us(LARGE_TIME); + writePin(_port,_pin,true); + _delay_us(SMALL_TIME); + writePin(_port,_pin,false); + _delay_us(LARGE_TIME); + break; + + case false: + //Der Code fuer '1' + writePin(_port,_pin,true); + _delay_us(LARGE_TIME); + writePin(_port,_pin,false); + _delay_us(SMALL_TIME); + writePin(_port,_pin,true); + _delay_us(SMALL_TIME); + writePin(_port,_pin,false); + _delay_us(LARGE_TIME); + break; + } +} + +void WirelessRelay::sync() +{ + writePin(_port,_pin,false); + _delay_us(SMALL_TIME*31); +} + +void WirelessRelay::on() +{ + for(short z = 0; z<10; z++) + { + sendId(); + sendBit(true); + sendBit(false); + sync(); + } +} + +void WirelessRelay::off() +{ + for(short z = 0; z<10; z++) + { + sendId(); + sendBit(false); + sendBit(true); + sync(); + } +} + +WirelessRelay::WirelessRelay( volatile unsigned char *port, const unsigned char pin, const uint16_t id):_id(id), _port(port), _pin(pin){} diff --git a/WirelessRelay.h b/WirelessRelay.h new file mode 100644 index 0000000..570962d --- /dev/null +++ b/WirelessRelay.h @@ -0,0 +1,25 @@ +#ifndef RF433_H +#define RF433_H + +#include +#include"writepin.h" + +#define LARGE_TIME 750 +#define SMALL_TIME 250 + +class WirelessRelay +{ +private: + const uint16_t _id; + volatile unsigned char *_port; + const unsigned char _pin; + void sendBit( const bool i); + void sync(); + void sendId(); + +public: + WirelessRelay( volatile unsigned char *port, const unsigned char pin, const uint16_t id); + void on(); + void off(); +}; +#endif diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..09efe36 --- /dev/null +++ b/main.cpp @@ -0,0 +1,178 @@ +#include +#include +#include +#include +#include "serial.h" +#include "writepin.h" +#include "WirelessRelay.h" +#include "pwm.h" +#include "encoder.h" + +bool serialDispatch(Serial* serial , WirelessRelay* relayOne, WirelessRelay* relayTow, WirelessRelay* relayThree, WirelessRelay* relayFour, Pwm16b* pwm) +{ + + if(serial->dataIsWaiting()) + { + char buffer[7]; + const int length = serial->getString(buffer, 7); + if(length == 4 && buffer[0] == 'S' && buffer[1] == 'T' && buffer[2] == 'A' && buffer[3] == 'T' ) return true; + else if(length == 5) + { + if (buffer[0] == 'C' && buffer[1] == 'H' ) + { + switch(buffer[2]) + { + case '0': + //writePin(&PORTB, PB3, buffer[4] == '1' ? true : false); pin is dead + serial->putString("OK\n"); + break; + case '1': + writePin(&PORTB, PB4, buffer[4] == '1' ? true : false); + serial->putString("OK\n"); + break; + case '2': + writePin(&PORTB, PB5, buffer[4] == '1' ? true : false); + serial->putString("OK\n"); + break; + } + } + else if (buffer[0] == 'W' && buffer[1] == 'R' ) + { + switch(buffer[2]) + { + case '0': + serial->putString("OK\n"); + buffer[4] == '1' ? relayOne->on() : relayOne->off(); + break; + case '1': + serial->putString("OK\n"); + buffer[4] == '1' ? relayTow->on() : relayTow->off(); + break; + case '2': + serial->putString("OK\n"); + buffer[4] == '1' ? relayThree->on() : relayThree->off(); + break; + } + } + else if (buffer[0] == 'O' && buffer[1] == 'P' && buffer[2] == 'T') + { + writePin(&PORTB, PB0, buffer[4] == '1' ? true : false); + serial->putString("OK\n"); + } + } + else if (length == 6 && buffer[0] == 'P' && buffer[1] == 'W' && buffer[2] == 'M') + { + char inNumber[2]; + inNumber[0]=buffer[4]; + inNumber[1]=buffer[5]; + pwm->setDuty(atoi(inNumber)); + serial->putString("OK\n"); + } + else if (length == 6 && buffer[0] == 'L' && buffer[1] == 'E' && buffer[2] == 'D') + { + switch(buffer[3]) + { + case '0': + writePin(&PORTC, PC4, buffer[5] == '1' ? true : false); + serial->putString("OK\n"); + break; + case '1': + writePin(&PORTC, PC5, buffer[5] == '1' ? true : false); + serial->putString("OK\n"); + break; + case '2': + writePin(&PORTD, PD4, buffer[5] == '1' ? true : false); + serial->putString("OK\n"); + break; + } + } + } + return false; +} + +void serialOutput(Serial* serial, Encoder* encoder, volatile unsigned char *inPort) +{ + serial->putString("VARS_"); + readPin( inPort, PC1 ) ? serial->putChar('0') : serial->putChar('1'); + readPin( inPort, PC2 ) ? serial->putChar('0') : serial->putChar('1'); + int16_t buffer = encoder->getPosition(); + serial->putString( (char*)&buffer, sizeof(buffer)); + serial->putChar('\n'); +} + +int main() +{ + DDRB = 0b11111111; + DDRD = 0b11111011;//(1 << PD3) | (1 << PD7) | (1 << PD3); + DDRC = 0x00; + PORTC = 0xFF; + + writePin(&PORTD, PD7, false); + bool StepperEnable = false; + + sei(); + + Serial serial; + + Pwm16b pwm; + pwm.setDuty(0x0000); + pwm.on(); + + + WirelessRelay relayOne(&PORTD, PD3, 0b1001110000000000); + WirelessRelay relayTow(&PORTD, PD3, 0b1001101000000000); + WirelessRelay relayThree(&PORTD, PD3, 0b1001100100000000); + WirelessRelay relayFour(&PORTD, PD3, 0b1001100010000000); + + Encoder encoder(&PINC, PC3, PC4); + + serial.putString("CNCextension v1.2 starting\n"); + + + while(true) + { + encoder.poll(); + if (serialDispatch(&serial, &relayOne, &relayTow, &relayThree, &relayFour, &pwm)) serialOutput(&serial, &encoder, &PINC ); + + writePin(&PORTB, PB2, ( PORTB & (1 << PB3) || PORTB & (1 << PB4) || PORTB & (1 << PB5)) ); + + //char buffer[16]; + //sprintf(buffer, "ENC_%05d\n", encoder.getPosition()); + //serial.putString(buffer); + + + if(!readPin(&PIND, PD2) && StepperEnable == false) + { + bool abort = false; + for (int i = 0; i < 100; i++) + { + if(readPin(&PIND, PD2)) abort = true; + _delay_ms(10); + } + if(!abort) + { + StepperEnable = true; + writePin(&PORTD, PD7, true); + //serial.putString("Enabeling Steppers\n"); + } + } + else if( readPin(&PIND, PD2) && StepperEnable == true ) + { + bool abort = false; + for (int i = 0; i < 10; i++) + { + if(!readPin(&PIND, PD2)) abort = true; + _delay_ms(5); + } + if(!abort) + { + StepperEnable = false; + writePin(&PORTD, PD7, false); + //serial.putString("Disabeling Steppers\n"); + } + } + + } + + return 0; //master interupt. +} diff --git a/pwm.cpp b/pwm.cpp new file mode 100644 index 0000000..bf88013 --- /dev/null +++ b/pwm.cpp @@ -0,0 +1,34 @@ +#include "pwm.h" + + +Pwm16b::Pwm16b() +{ + DDRB |= (1< + +class Pwm16b +{ +public: + Pwm16b(); + ~Pwm16b(); + void setDuty( const uint16_t duty ); + void off(); + void on(); +}; + +#endif diff --git a/serial.cpp b/serial.cpp new file mode 100644 index 0000000..86b0483 --- /dev/null +++ b/serial.cpp @@ -0,0 +1,90 @@ +#include "serial.h" + +char rxBuffer[BUFFER_SIZE]; +volatile uint16_t interruptIndex = 0; + +ISR (USART_RX_vect) //I have seen worse interrupt sintax +{ + rxBuffer[interruptIndex % BUFFER_SIZE] = UDR0; + interruptIndex++; +} + +Serial::Serial() +{ + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; + UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); + UCSR0B = _BV(RXEN0) | _BV(TXEN0); //Enable RX and TX + UCSR0B |= (1 << RXCIE0); //Enable Rx interuppt +} + +void Serial::putChar(const char c) +{ + loop_until_bit_is_set(UCSR0A, UDRE0); + UDR0 = c; +} + +void Serial::putString(const char* in, const unsigned int length) +{ + for(unsigned int i = 0; i < length; i++) + { + putChar(in[i]); + } +} + +void Serial::putString(const char in[]) +{ + for(unsigned int i = 0; i < strlen(in); i++) + { + putChar(in[i]); + } +} + +bool Serial::dataIsWaiting() +{ + return (interruptIndex > _rxIndex); +} + +char Serial::getChar() +{ + if( _rxIndex >= (32768) - 2*BUFFER_SIZE ) flush(); //may explode only occasionaly + if(dataIsWaiting()) + { + _rxIndex++; + return rxBuffer[(_rxIndex -1) % BUFFER_SIZE]; + } + else return '\0'; +} + +int Serial::getString(char* buffer, const int bufferLength) +{ + int i = 0; + for(; i <= (interruptIndex-_rxIndex) && i <= BUFFER_SIZE && rxBuffer[(_rxIndex+i) % BUFFER_SIZE] != _terminator; i++); + + if( i < (interruptIndex-_rxIndex) && i > 0) + { + for(int j = 0 ; j < i && j < bufferLength ; j++) + { + buffer[j] = getChar(); + } + _rxIndex++; + } + else + { + i = 0; + if( _rxIndex >= (32768) - 2*BUFFER_SIZE ) flush(); + } + + if (rxBuffer[(_rxIndex+i) % BUFFER_SIZE] == _terminator) _rxIndex++; + + return i; +} + +void Serial::flush() +{ + _rxIndex = 0; + interruptIndex = 0; + for(int i = 0; i < BUFFER_SIZE; i++) rxBuffer[i] = ' '; +} + +void Serial::setTerminator(char terminator){_terminator = terminator;} diff --git a/serial.h b/serial.h new file mode 100644 index 0000000..437b0c3 --- /dev/null +++ b/serial.h @@ -0,0 +1,31 @@ +#ifndef SERIAL_H +#define SERIAL_H + +#define BAUD 38400 +#define BUFFER_SIZE 64 + +#include +#include +#include +#include + +class Serial +{ +private: + char _terminator = '\n'; + uint16_t _rxIndex=0; + +public: + Serial(); + void putChar(const char c); + void putString(const char* in, const unsigned int length); + void putString(const char in[]); + bool dataIsWaiting(); + char getChar(); + int getString(char* buffer, const int bufferLength); + void flush(); + void setTerminator(const char terminator); +}; + +#endif + diff --git a/writepin.h b/writepin.h new file mode 100644 index 0000000..4ef214f --- /dev/null +++ b/writepin.h @@ -0,0 +1,13 @@ +#ifndef WRITEPIN_H +#define WRITEPIN_H +#include + +inline void writePin(volatile unsigned char *port, const unsigned char pin, const bool state) //waste 2 cycles +{ + *port &= ~(1 << pin); + if(state) *port |= (1 << pin); +} + +inline bool readPin( volatile unsigned char *inPort, const unsigned char pin){ return (bool) (*inPort & (1 << pin));} + +#endif