From 51a5e6fc2854c1b2a5f33e20ee0882bb466a7fc6 Mon Sep 17 00:00:00 2001 From: Carl Klemm Date: Mon, 6 May 2019 19:06:49 +0200 Subject: [PATCH] inital commit --- CMakeLists.txt | 54 +++++++++++++++++++ buttons.h | 44 ++++++++++++++++ comperator.cpp | 22 ++++++++ comperator.h | 13 +++++ eeprom.h | 51 ++++++++++++++++++ main.cpp | 137 +++++++++++++++++++++++++++++++++++++++++++++++++ stepper.cpp | 92 +++++++++++++++++++++++++++++++++ stepper.h | 42 +++++++++++++++ writepin.cpp | 20 ++++++++ writepin.h | 14 +++++ 10 files changed, 489 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 buttons.h create mode 100644 comperator.cpp create mode 100644 comperator.h create mode 100644 eeprom.h create mode 100644 main.cpp create mode 100644 stepper.cpp create mode 100644 stepper.h create mode 100644 writepin.cpp create mode 100644 writepin.h 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