inital commit
This commit is contained in:
commit
51a5e6fc28
54
CMakeLists.txt
Normal file
54
CMakeLists.txt
Normal file
@ -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}
|
||||
)
|
44
buttons.h
Normal file
44
buttons.h
Normal file
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <avr/io.h>
|
||||
#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];
|
||||
}
|
||||
}
|
||||
}
|
22
comperator.cpp
Normal file
22
comperator.cpp
Normal file
@ -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;
|
||||
}
|
13
comperator.h
Normal file
13
comperator.h
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include <avr/io.h>
|
||||
|
||||
class Comperator
|
||||
{
|
||||
static constexpr bool INTERNAL_REFERANCE = true;
|
||||
public:
|
||||
Comperator();
|
||||
|
||||
static void on();
|
||||
static void off();
|
||||
static bool compare();
|
||||
};
|
51
eeprom.h
Normal file
51
eeprom.h
Normal file
@ -0,0 +1,51 @@
|
||||
void EEPROM_write_char(uint16_t address, unsigned char data)
|
||||
{
|
||||
//Wait for completion of previous write
|
||||
while(EECR & (1<<EEPE));
|
||||
//Set up address and Data Registers
|
||||
EEAR = address;
|
||||
EEDR = data;
|
||||
//Write logical one to EEMPE
|
||||
EECR |= (1<<EEMPE);
|
||||
//Start eeprom write by setting EEPE
|
||||
EECR |= (1<<EEPE);
|
||||
}
|
||||
|
||||
unsigned char EEPROM_read_char(uint16_t uiAddress)
|
||||
{
|
||||
// Wait for completion of previous write
|
||||
while(EECR & (1<<EEPE));
|
||||
//Set up address register
|
||||
EEAR = uiAddress;
|
||||
//Start eeprom read by writing EERE
|
||||
EECR |= (1<<EERE);
|
||||
//Return data from Data Register
|
||||
return EEDR;
|
||||
}
|
||||
|
||||
void EEPROM_write_string(uint16_t address, char* buffer, uint16_t length)
|
||||
{
|
||||
for(uint16_t i = 0; i < length; i++) EEPROM_write_char( address+i, buffer[i] );
|
||||
}
|
||||
|
||||
void EEPROM_read_string(uint16_t address, char* buffer, uint16_t length)
|
||||
{
|
||||
for(uint16_t i = 0; i < length; i++) buffer[i] = EEPROM_read_char( address+i);
|
||||
}
|
||||
|
||||
template <class T> void EEPROM_write_class(uint16_t address, T& in)
|
||||
{
|
||||
EEPROM_write_string( address, reinterpret_cast<char*>(&in), sizeof(in));
|
||||
}
|
||||
|
||||
template <class T> T EEPROM_read_class(uint16_t address)
|
||||
{
|
||||
char data[sizeof(T)];
|
||||
EEPROM_read_string( address, data, sizeof(T) );
|
||||
return *reinterpret_cast<T*>(data);
|
||||
}
|
||||
|
||||
template <class T> void EEPROM_read_class(uint16_t address, T* in)
|
||||
{
|
||||
EEPROM_read_string( address, reinterpret_cast<char*>(in), sizeof(T) );
|
||||
}
|
137
main.cpp
Normal file
137
main.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
#include <stdint.h>
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/sleep.h>
|
||||
#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<Stepper*>(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<void*>(&stepper));
|
||||
|
||||
uint8_t timer = 0;
|
||||
|
||||
while(true)
|
||||
{
|
||||
if(++timer == 0)buttons.tick();
|
||||
stepper.tick();
|
||||
_delay_us(50);
|
||||
}
|
||||
}
|
||||
|
92
stepper.cpp
Normal file
92
stepper.cpp
Normal file
@ -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;
|
||||
}
|
42
stepper.h
Normal file
42
stepper.h
Normal file
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
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);
|
||||
};
|
20
writepin.cpp
Normal file
20
writepin.cpp
Normal file
@ -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));}
|
14
writepin.h
Normal file
14
writepin.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef WRITEPIN_H
|
||||
#define WRITEPIN_H
|
||||
#include <avr/io.h>
|
||||
|
||||
|
||||
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
|
Loading…
x
Reference in New Issue
Block a user