commit 51a5e6fc2854c1b2a5f33e20ee0882bb466a7fc6 Author: Carl Klemm Date: Mon May 6 19:06:49 2019 +0200 inital commit diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a2ddd01 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,54 @@ +# Project name +project(asteleMotor) + +# CMake version +cmake_minimum_required(VERSION 2.6) + +# Options +set(MCU "attiny2313" CACHE STRING "Processor Type") +set(CPU_SPEED "4000000" 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 "usbasp" CACHE STRING "Programmer Type") +set(COMPILE_FLAGS "" CACHE STRING "Additional Compiler Flags") + +# Set own source files +set(SRC_FILES main.cpp writepin.cpp comperator.cpp stepper.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 -flto -Wall -std=c++17 ) +add_definitions(-fno-exceptions -ffunction-sections -fno-rtti -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 "-s -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) +find_program(AR_AVRSIZE NAMES avr-size 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_AVRSIZE} -C ${PROJECT_NAME} + COMMAND ${AR_AVRDUDE} -v -p ${MCU} -c ${PROGRAMMER} -D -U flash:w:${PROJECT_NAME}.hex + DEPENDS ${PROJECT_NAME} + ) + + message(STATUS "${CPU_SPEED}") + +add_custom_target(export +COMMAND ${CMAKE_OBJCOPY} -j .text -j .data -O ihex ${PROJECT_NAME} ${PROJECT_NAME}.hex +COMMAND ${AR_AVRSIZE} -C ${PROJECT_NAME} +DEPENDS ${PROJECT_NAME} +) diff --git a/buttons.h b/buttons.h new file mode 100644 index 0000000..ff5e766 --- /dev/null +++ b/buttons.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include "writepin.h" + +class Buttons +{ + public: + + static constexpr uint8_t PRESSED = 0; + static constexpr uint8_t LONG_PRESSED = 1; + static constexpr uint8_t RELEASED = 2; + + private: + volatile uint8_t * const pinReg = &PIND; + static constexpr uint8_t button[] = { PD5, PD6 }; + static constexpr uint8_t buttonsAmount = sizeof(button); + uint8_t buttonCount[buttonsAmount] = {}; + + void* _userData; + void (*_eventHandler)(uint8_t index, uint8_t type, void* data); + + public: + Buttons(void (*eventHandler)(uint8_t index, uint8_t type, void* data), void* userData = nullptr): _userData(userData), _eventHandler(eventHandler){} + void tick(); +}; + +void Buttons::tick() +{ + for(uint8_t i = 0; i < buttonsAmount; ++i) + { + if(readPin(pinReg, button[i]) == true) + { + if(buttonCount[i] > 2) _eventHandler(i, RELEASED, _userData); + buttonCount[i] = 0; + } + else + { + if(buttonCount[i] == 3) _eventHandler(i, PRESSED, _userData); + else if(buttonCount[i] == 100) _eventHandler(i, LONG_PRESSED, _userData); + ++buttonCount[i]; + } + } +} diff --git a/comperator.cpp b/comperator.cpp new file mode 100644 index 0000000..ce3dda2 --- /dev/null +++ b/comperator.cpp @@ -0,0 +1,22 @@ +#include "comperator.h" + +Comperator::Comperator() +{ + if constexpr(INTERNAL_REFERANCE) ACSR = 0b01000001; + else ACSR = 0b00000011; +} + +void Comperator::on() +{ + ACSR &= 0b01111111; +} + +void Comperator::off() +{ + ACSR |= 0b10000000; +} + +bool Comperator::compare() +{ + return ACSR & 0b00100000; +} diff --git a/comperator.h b/comperator.h new file mode 100644 index 0000000..6ba25b1 --- /dev/null +++ b/comperator.h @@ -0,0 +1,13 @@ +#pragma once +#include + +class Comperator +{ + static constexpr bool INTERNAL_REFERANCE = true; +public: + Comperator(); + + static void on(); + static void off(); + static bool compare(); +}; diff --git a/eeprom.h b/eeprom.h new file mode 100644 index 0000000..ee9b531 --- /dev/null +++ b/eeprom.h @@ -0,0 +1,51 @@ +void EEPROM_write_char(uint16_t address, unsigned char data) +{ + //Wait for completion of previous write + while(EECR & (1< void EEPROM_write_class(uint16_t address, T& in) +{ + EEPROM_write_string( address, reinterpret_cast(&in), sizeof(in)); +} + +template T EEPROM_read_class(uint16_t address) +{ + char data[sizeof(T)]; + EEPROM_read_string( address, data, sizeof(T) ); + return *reinterpret_cast(data); +} + +template void EEPROM_read_class(uint16_t address, T* in) +{ + EEPROM_read_string( address, reinterpret_cast(in), sizeof(T) ); +} diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..90a040f --- /dev/null +++ b/main.cpp @@ -0,0 +1,137 @@ +#include +#include +#include +#include +#include +#include "stepper.h" +#include "writepin.h" +#include "comperator.h" +#include "buttons.h" +#include "eeprom.h" + +#define LED_1_PIN PB3 +#define LED_2_PIN PB4 + +#define BUTTON_1_PIN PD5 +#define BUTTON_2_PIN PD6 + +bool setup = false; +static bool buttonLongpressed[2]; +uint8_t lockedSpeed = 180; + +void debugBlink(bool fast = true) +{ + _delay_ms(100); + if(!fast) _delay_ms(200); + PORTB |= 1 << LED_1_PIN; + _delay_ms(100); + if(!fast) _delay_ms(200); + PORTB &= ~(1 << LED_1_PIN); +} + +void buttonHandler(uint8_t index, uint8_t type, void* data) +{ + Stepper* stepper = reinterpret_cast(data); + if(setup == false) + { + if(type == Buttons::PRESSED) + { + if(index == 0) + { + stepper->setSpeed(230); + stepper->setEndlesMove(true, true); + } + else + { + stepper->setSpeed(230); + stepper->setEndlesMove(true, false); + } + } + else if(type == Buttons::RELEASED) + { + stepper->setSpeed(lockedSpeed); + stepper->setEndlesMove(true, true); + buttonLongpressed[0] = false; + buttonLongpressed[1] = false; + } + else if(type == Buttons::LONG_PRESSED) + { + buttonLongpressed[index] = true; + if(buttonLongpressed[0] && buttonLongpressed[1]) + { + writePin(&PORTB, LED_2_PIN, true); + writePin(&PORTB, LED_1_PIN, false); + setup = true; + buttonLongpressed[0] = false; + buttonLongpressed[1] = false; + stepper->setSpeed(lockedSpeed); + stepper->setEndlesMove(true, true); + debugBlink(); + debugBlink(); + debugBlink(); + } + } + } + else + { + if(type == Buttons::PRESSED) writePin(&PORTB, LED_1_PIN, true); + if(type == Buttons::RELEASED) + { + writePin(&PORTB, LED_1_PIN, false); + if(index == 0) + { + lockedSpeed+=5; + } + else + { + lockedSpeed-=5; + } + EEPROM_write_char(0, lockedSpeed); + stepper->setSpeed(lockedSpeed); + } + else if(type == Buttons::LONG_PRESSED) + { + buttonLongpressed[index] = true; + if(buttonLongpressed[0] && buttonLongpressed[1]) + { + writePin(&PORTB, LED_2_PIN, false); + writePin(&PORTB, LED_1_PIN, true); + setup = false; + buttonLongpressed[0] = false; + buttonLongpressed[1] = false; + stepper->setSpeed(lockedSpeed); + stepper->setEndlesMove(true, true); + } + } + } +} + +int main() +{ + DDRB = 1 << LED_1_PIN | 1 << LED_2_PIN; + DDRD = 1 << PD0 | 1 << PD1 | 1 << PD2 | 1 << PD3; + PORTD = 1 << BUTTON_1_PIN | 1 << BUTTON_2_PIN; + + if(EEPROM_read_char(0) != 0) lockedSpeed = EEPROM_read_char(0); + + Stepper stepper(&PORTD, PD0, PD1, PD2, PD3); + + debugBlink(false); + debugBlink(false); + + writePin(&PORTB, LED_1_PIN, true); + stepper.setSpeed(180); + stepper.setEndlesMove(true); + + Buttons buttons(&buttonHandler, reinterpret_cast(&stepper)); + + uint8_t timer = 0; + + while(true) + { + if(++timer == 0)buttons.tick(); + stepper.tick(); + _delay_us(50); + } +} + diff --git a/stepper.cpp b/stepper.cpp new file mode 100644 index 0000000..34a0327 --- /dev/null +++ b/stepper.cpp @@ -0,0 +1,92 @@ + +#include "stepper.h" +#include "writepin.h" + +void Stepper::tick() +{ + if(++_tickCounter > UINT8_MAX - (_speed>>8) ) + { + if(_targetStep != _currentStep) + { + step(_targetStep > _currentStep); + } + else if(endlessMove) step(endlessDriection); + _tickCounter = 0; + } + if(_speed>>8 < _targetSpeed) _speed = _speed + acceleration; + else if(_speed>>8 > _targetSpeed)_speed = _speed - acceleration;; +} + +void Stepper::moveTo(const int32_t step) +{ + _targetStep = step; +} + +void Stepper::moveRelative(const int16_t dist) +{ + moveTo(_targetStep + dist); +} + +void Stepper::setSpeed(const uint8_t speed) +{ + _targetSpeed = speed; + if(_targetSpeed < speedFloor) _targetSpeed = speedFloor; +} + +void Stepper::setEndlesMove(bool endless, bool direction) +{ + endlessMove = endless; + if(direction != endlessDriection) + { + _speed = speedFloor; + endlessDriection = direction; + } +} + +uint32_t Stepper::isAt() +{ + return _currentStep; +} + +bool Stepper::isStoped() +{ + return _currentStep == _targetStep; +} + +void Stepper::step(bool direction) +{ + switch(_currentStep & 0x03) + { + case 0: + writePin(_port, _pinA, true); + writePin(_port, _pinB, false); + writePin(_port, _pinC, false); + writePin(_port, _pinD, true); + break; + case 1: + writePin(_port, _pinA, true); + writePin(_port, _pinB, true); + writePin(_port, _pinC, false); + writePin(_port, _pinD, false); + break; + case 2: + writePin(_port, _pinA, false); + writePin(_port, _pinB, true); + writePin(_port, _pinC, true); + writePin(_port, _pinD, false); + break; + case 3: + writePin(_port, _pinA, false); + writePin(_port, _pinB, false); + writePin(_port, _pinC, true); + writePin(_port, _pinD, true); + break; + default: + writePin(_port, _pinA, false); + writePin(_port, _pinB, false); + writePin(_port, _pinC, false); + writePin(_port, _pinD, false); + } + _currentStep = _currentStep + (direction ? 1 : -1); + if(endlessMove) _targetStep = _currentStep; +} diff --git a/stepper.h b/stepper.h new file mode 100644 index 0000000..238fd08 --- /dev/null +++ b/stepper.h @@ -0,0 +1,42 @@ +#pragma once + +#include + +class Stepper +{ +private: + volatile uint8_t * const _port; + const uint8_t _pinA; + const uint8_t _pinB; + const uint8_t _pinC; + const uint8_t _pinD; + + static constexpr uint8_t acceleration = 5; + static constexpr uint8_t speedFloor = 50; + + bool endlessMove = false; + bool endlessDriection = true; + + uint16_t _speed = speedFloor; + uint8_t _targetSpeed = 220; + uint8_t _stepInterval = 0; + + uint16_t _tickCounter = 0; + + int32_t _currentStep = 0; + int32_t _targetStep = 0; + + void step(bool direction); + + +public: + + Stepper( volatile uint8_t * const port, const uint8_t pinA, const uint8_t pinB, const uint8_t pinC, const uint8_t pinD): _port(port), _pinA(pinA), _pinB(pinB), _pinC(pinC), _pinD(pinD){} + void tick(); + void moveTo(const int32_t step); + void moveRelative(const int16_t dist); + void setSpeed(const uint8_t speed); + uint32_t isAt(); + bool isStoped(); + void setEndlesMove(bool endless, bool direction = true); +}; diff --git a/writepin.cpp b/writepin.cpp new file mode 100644 index 0000000..2caaf88 --- /dev/null +++ b/writepin.cpp @@ -0,0 +1,20 @@ +#include "writepin.h" + +void writePin(volatile unsigned char * const port, const unsigned char pin, const bool state) +{ + *port = (*port & ~(1 << pin)) | (1 << pin)*state; + //if(!state) *port &= ~(1 << pin); + //else *port |= (1 << pin); +} + +void setBit( volatile unsigned char * const reg, const unsigned char bit, const bool value ) +{ + writePin(reg, bit, value); +} + +void setDirection( volatile unsigned char * const portDirReg, const unsigned char pin, const bool makeOutput ) +{ + writePin(portDirReg, pin, makeOutput); +} + +bool readPin( volatile const unsigned char * const inPort, const unsigned char pin){ return (bool) (*inPort & (1 << pin));} diff --git a/writepin.h b/writepin.h new file mode 100644 index 0000000..4e680bb --- /dev/null +++ b/writepin.h @@ -0,0 +1,14 @@ +#ifndef WRITEPIN_H +#define WRITEPIN_H +#include + + +void writePin(volatile unsigned char * const port, const unsigned char pin, const bool state); + +void setBit( volatile unsigned char * const reg, const unsigned char bit, const bool value ); + +void setDirection( volatile unsigned char * const portDirReg, const unsigned char pin, const bool makeOutput ); + +bool readPin( volatile const unsigned char * const inPort, const unsigned char pin); + +#endif