From e2e53267c646144564d1832ea29758d771bfb60d Mon Sep 17 00:00:00 2001 From: IMback Date: Sun, 14 May 2017 23:29:55 +0200 Subject: [PATCH] Initial commit --- CMakeLists.txt | 50 +++++++++++++ WirelessRelay.cpp | 75 +++++++++++++++++++ WirelessRelay.h | 25 +++++++ main.cpp | 178 ++++++++++++++++++++++++++++++++++++++++++++++ pwm.cpp | 34 +++++++++ pwm.h | 16 +++++ serial.cpp | 90 +++++++++++++++++++++++ serial.h | 31 ++++++++ writepin.h | 13 ++++ 9 files changed, 512 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 WirelessRelay.cpp create mode 100644 WirelessRelay.h create mode 100644 main.cpp create mode 100644 pwm.cpp create mode 100644 pwm.h create mode 100644 serial.cpp create mode 100644 serial.h create mode 100644 writepin.h 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