add support for turnouts
This commit is contained in:
@ -17,7 +17,7 @@ set(PORT_SPEED "57600" CACHE STRING "Serial Port Speed")
|
|||||||
set(PROGRAMMER "stk500v1" CACHE STRING "Programmer Type")
|
set(PROGRAMMER "stk500v1" CACHE STRING "Programmer Type")
|
||||||
set(COMPILE_FLAGS "" CACHE STRING "Additional Compiler Flags")
|
set(COMPILE_FLAGS "" CACHE STRING "Additional Compiler Flags")
|
||||||
|
|
||||||
set(SRC_FILES main.cpp serial.cpp train.cpp item.cpp)
|
set(SRC_FILES main.cpp serial.cpp train.cpp item.cpp turnout.cpp)
|
||||||
|
|
||||||
# Compiler suite specification
|
# Compiler suite specification
|
||||||
set(CMAKE_C_COMPILER /usr/bin/avr-gcc)
|
set(CMAKE_C_COMPILER /usr/bin/avr-gcc)
|
||||||
|
2
item.cpp
2
item.cpp
@ -74,7 +74,7 @@ void Item::sendAddress(uint8_t address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item::sendRawAddr(const uint16_t address, const uint16_t data)
|
void Item::sendRawAddr(const uint8_t address, const uint16_t data)
|
||||||
{
|
{
|
||||||
for(uint8_t j = 0; j < SEND_COUNT; j++)
|
for(uint8_t j = 0; j < SEND_COUNT; j++)
|
||||||
{
|
{
|
||||||
|
3
item.h
3
item.h
@ -1,3 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
#include "writepin.h"
|
#include "writepin.h"
|
||||||
#include <util/delay.h>
|
#include <util/delay.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -38,7 +39,7 @@ public:
|
|||||||
Item(const uint8_t address);
|
Item(const uint8_t address);
|
||||||
|
|
||||||
void sendRaw(const uint16_t data);
|
void sendRaw(const uint16_t data);
|
||||||
static void sendRawAddr(const uint16_t address, const uint16_t data);
|
static void sendRawAddr(const uint8_t address, const uint16_t data);
|
||||||
|
|
||||||
void setAddress(const uint8_t address);
|
void setAddress(const uint8_t address);
|
||||||
uint8_t getAddress();
|
uint8_t getAddress();
|
||||||
|
200
main.cpp
200
main.cpp
@ -10,6 +10,7 @@
|
|||||||
#include "bitrep.h"
|
#include "bitrep.h"
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
#include "staticvector.h"
|
#include "staticvector.h"
|
||||||
|
#include "turnout.h"
|
||||||
|
|
||||||
#define COMMAND_BUFFER_SIZE 64
|
#define COMMAND_BUFFER_SIZE 64
|
||||||
#define SNPRINTF_BUFFER_SIZE 128
|
#define SNPRINTF_BUFFER_SIZE 128
|
||||||
@ -18,6 +19,7 @@
|
|||||||
char buffer[SNPRINTF_BUFFER_SIZE];
|
char buffer[SNPRINTF_BUFFER_SIZE];
|
||||||
|
|
||||||
SVector<Train, 16> trains;
|
SVector<Train, 16> trains;
|
||||||
|
SVector<Turnout, 32> turnouts;
|
||||||
|
|
||||||
bool autoff = true;
|
bool autoff = true;
|
||||||
bool powerIsOn = true;
|
bool powerIsOn = true;
|
||||||
@ -53,23 +55,32 @@ void timer0InterruptEnable(const bool enable)
|
|||||||
void save_state()
|
void save_state()
|
||||||
{
|
{
|
||||||
cli();
|
cli();
|
||||||
EEPROM_write_char( 0, trains.count() );
|
EEPROM_write_char( 0, trains.count());
|
||||||
EEPROM_write_char( 1, autoff );
|
EEPROM_write_char( 1, autoff);
|
||||||
|
EEPROM_write_char( 2, trains.maxSize());
|
||||||
|
EEPROM_write_char( 3, turnouts.count());
|
||||||
|
EEPROM_write_char( 4, turnouts.maxSize());
|
||||||
for(uint16_t i = 0; i < trains.count(); i++)
|
for(uint16_t i = 0; i < trains.count(); i++)
|
||||||
{
|
{
|
||||||
EEPROM_write_char( i*2+32, trains[i].getAddress());
|
EEPROM_write_char( i*2+32, trains[i].getAddress());
|
||||||
EEPROM_write_char( i*2+32+1, trains[i].getFunctionMask());
|
EEPROM_write_char( i*2+32+1, trains[i].getFunctionMask());
|
||||||
}
|
}
|
||||||
|
for(uint16_t i = 0; i < turnouts.count(); i++)
|
||||||
|
{
|
||||||
|
EEPROM_write_char( i*2+32+trains.maxSize()*2, turnouts[i].getAddress());
|
||||||
|
EEPROM_write_char( i*2+32+1+trains.maxSize()*2, turnouts[i].getSubaddress());
|
||||||
|
}
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
void restore_state()
|
void restore_state()
|
||||||
{
|
{
|
||||||
uint8_t trainCount = EEPROM_read_char(0);
|
uint8_t trainCount = EEPROM_read_char(0);
|
||||||
|
uint8_t turnoutCount = EEPROM_read_char(3);
|
||||||
autoff = EEPROM_read_char(1);
|
autoff = EEPROM_read_char(1);
|
||||||
|
|
||||||
trains.clear();
|
trains.clear();
|
||||||
if(trainCount > trains.maxSize() )
|
if(trainCount > trains.maxSize() || trains.maxSize() != EEPROM_read_char(2) )
|
||||||
{
|
{
|
||||||
for(uint16_t i = 0; i < EPPROM_SIZE; i++)
|
for(uint16_t i = 0; i < EPPROM_SIZE; i++)
|
||||||
EEPROM_write_char(i, 0);
|
EEPROM_write_char(i, 0);
|
||||||
@ -78,6 +89,8 @@ void restore_state()
|
|||||||
{
|
{
|
||||||
for(uint8_t i = 0; i < trainCount; i++)
|
for(uint8_t i = 0; i < trainCount; i++)
|
||||||
trains.push_back(Train(EEPROM_read_char(32+i*2), EEPROM_read_char(32+1+i*2)));
|
trains.push_back(Train(EEPROM_read_char(32+i*2), EEPROM_read_char(32+1+i*2)));
|
||||||
|
for(uint8_t i = 0; i < turnoutCount; i++)
|
||||||
|
turnouts.push_back(Turnout(EEPROM_read_char(32+i*2+trains.maxSize()*2), EEPROM_read_char(32+1+i*2+trains.maxSize()*2)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,12 +99,16 @@ inline static void printHelp(Serial* serial)
|
|||||||
serial->write_p(PSTR("Available Commands: \n\
|
serial->write_p(PSTR("Available Commands: \n\
|
||||||
help : Show this prompt.\n\
|
help : Show this prompt.\n\
|
||||||
train add [address] [functionmask] : Add train.\n\
|
train add [address] [functionmask] : Add train.\n\
|
||||||
train delete : Delete last train.\n\
|
train [nn] delete : Delete last train.\n\
|
||||||
train list : Print list of saved trains.\n\
|
train list : Print list of saved trains.\n\
|
||||||
train [nn] s(top) : Stop nth train.\n\
|
train [nn] s(top) : Stop nth train.\n\
|
||||||
train [nn] s(peed) [sp] : Set nth train speed.\n\
|
train [nn] s(peed) [sp] : Set nth train speed.\n\
|
||||||
train [nn] function [x] : Toggle x'ed fuction on train n.\n\
|
train [nn] function [x] : Toggle x'ed fuction on train n.\n\
|
||||||
train [nn] r(everse) : Reverse train n.\n\
|
train [nn] r(everse) : Reverse train n.\n\
|
||||||
|
turnout add [address] [subaddress] : Add a turnout\n\
|
||||||
|
turnout list : List turnouts\n\
|
||||||
|
turnout set [left/right] : Set turnout direction\n\
|
||||||
|
turnout delete [nn] : Delete Turnout\n\
|
||||||
stop : stop all trains\n\
|
stop : stop all trains\n\
|
||||||
power off : power off the rail\n\
|
power off : power off the rail\n\
|
||||||
power on : power on the rail\n\
|
power on : power on the rail\n\
|
||||||
@ -100,6 +117,133 @@ inline static void printHelp(Serial* serial)
|
|||||||
erase : Erase epprom.\n"));
|
erase : Erase epprom.\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setPower(bool on)
|
||||||
|
{
|
||||||
|
if(powerIsOn != on)
|
||||||
|
{
|
||||||
|
powerIsOn = on;
|
||||||
|
|
||||||
|
if(on)
|
||||||
|
{
|
||||||
|
Train::setOutput(Train::LOW);
|
||||||
|
_delay_ms(100);
|
||||||
|
timer0InterruptEnable(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timer0InterruptEnable(false);
|
||||||
|
Train::setOutput(Train::OFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int turnoutDispatch(char* inBuffer, Serial* serial)
|
||||||
|
{
|
||||||
|
if( strcmp(inBuffer, "add") == 0 )
|
||||||
|
{
|
||||||
|
char* token = strtok(NULL, " ");
|
||||||
|
uint8_t address = 0;
|
||||||
|
if(token != NULL)
|
||||||
|
address = strtol(token, nullptr, 10);
|
||||||
|
if(address != 0 && turnouts.remainingCapacity() > 0)
|
||||||
|
{
|
||||||
|
uint8_t subaddress = 0;
|
||||||
|
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
if(token != NULL)
|
||||||
|
subaddress = strtol(token, nullptr, 10);
|
||||||
|
|
||||||
|
turnouts.push_back(Turnout(address, subaddress));
|
||||||
|
|
||||||
|
uint8_t size = snprintf(buffer, SNPRINTF_BUFFER_SIZE, "TUNROUT saved! NUMBER: %u ADDRESS: %u SUBADDRESS: %u\n",
|
||||||
|
turnouts.count()-1,
|
||||||
|
address,
|
||||||
|
turnouts.back().getSubaddress());
|
||||||
|
serial->write(buffer, size);
|
||||||
|
|
||||||
|
save_state();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
serial->write_p(PSTR("Usage: turnout add [address] [subaddress]"));
|
||||||
|
}
|
||||||
|
else if( strcmp(inBuffer, "list") == 0 )
|
||||||
|
{
|
||||||
|
serial->write_p(PSTR("Turnouts:\n"));
|
||||||
|
for(uint8_t i = 0; i < turnouts.count(); i++)
|
||||||
|
{
|
||||||
|
snprintf(buffer, SNPRINTF_BUFFER_SIZE, "NUMBER: %u ADDRESS: %u SUBADDRESS: %u CURRENT PACKET: %x DIRECTION: %u\n",
|
||||||
|
i, turnouts[i].getAddress(), turnouts[i].getSubaddress(),
|
||||||
|
turnouts[i].getPacket(), turnouts[i].getDirection());
|
||||||
|
serial->write(buffer, SNPRINTF_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
serial->putChar('\n');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint8_t id = strtol(inBuffer, nullptr, 10);
|
||||||
|
if(id < turnouts.count() )
|
||||||
|
{
|
||||||
|
setPower(true);
|
||||||
|
char* token = strtok(NULL, " ");
|
||||||
|
if(token != NULL && strcmp(token, "set") == 0 )
|
||||||
|
{
|
||||||
|
char* boolToken = strtok(NULL, " ");
|
||||||
|
if(token != NULL && boolToken != NULL)
|
||||||
|
{
|
||||||
|
bool direction = (strcmp(boolToken, "right") == 0);
|
||||||
|
turnouts[id].setDirection(direction);
|
||||||
|
serial->write_p(PSTR("Set turnout direction "));
|
||||||
|
serial->write(direction ? "right\n" : "left\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(token != NULL && strcmp(token, "raw") == 0 )
|
||||||
|
{
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
serial->flush();
|
||||||
|
if(token != NULL)
|
||||||
|
{
|
||||||
|
cli();
|
||||||
|
uint16_t i = strtol(token, nullptr, 16 );
|
||||||
|
snprintf(buffer, SNPRINTF_BUFFER_SIZE, "SENDING: %x to %x\n", i, turnouts[id].getAddress());
|
||||||
|
serial->write(buffer, strlen(buffer));
|
||||||
|
while(!serial->dataIsWaiting())
|
||||||
|
{
|
||||||
|
turnouts[id].sendRaw(i);
|
||||||
|
sei();
|
||||||
|
_delay_ms(20);
|
||||||
|
cli();
|
||||||
|
}
|
||||||
|
serial->write_p(PSTR("Finished\n"));
|
||||||
|
serial->flush();
|
||||||
|
sei();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(token != NULL && strcmp(token, "delete") == 0)
|
||||||
|
{
|
||||||
|
turnouts.erase(id);
|
||||||
|
serial->write_p(PSTR("Turnout: "));
|
||||||
|
serial->write(id);
|
||||||
|
serial->write_p(PSTR(" deleted\n"));
|
||||||
|
save_state();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serial->write_p(PSTR("Not a valid command\n"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serial->write_p(PSTR("Id out of range.\n"));
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
int trainDispatch(char* inBuffer, Serial* serial)
|
int trainDispatch(char* inBuffer, Serial* serial)
|
||||||
{
|
{
|
||||||
@ -136,7 +280,7 @@ int trainDispatch(char* inBuffer, Serial* serial)
|
|||||||
serial->write_p(PSTR("Trains:\n"));
|
serial->write_p(PSTR("Trains:\n"));
|
||||||
for(uint8_t i = 0; i < trains.count(); i++)
|
for(uint8_t i = 0; i < trains.count(); i++)
|
||||||
{
|
{
|
||||||
snprintf(buffer, SNPRINTF_BUFFER_SIZE, "NUMBER: %u ID: %u CURRENT PACKET: %x SPEED: %i FUNCTIONS: %s FUNCTIONMASK: %s\n",
|
snprintf(buffer, SNPRINTF_BUFFER_SIZE, "NUMBER: %u ADDRESS: %u CURRENT PACKET: %x SPEED: %i FUNCTIONS: %s FUNCTIONMASK: %s\n",
|
||||||
i, trains[i].getAddress(),
|
i, trains[i].getAddress(),
|
||||||
trains[i].getLastPacket(), trains[i].getSpeed(),
|
trains[i].getLastPacket(), trains[i].getSpeed(),
|
||||||
bit_rep[trains[i].getFunctions() & 0x0F], bit_rep[trains[i].getFunctionMask() & 0x0F]);
|
bit_rep[trains[i].getFunctions() & 0x0F], bit_rep[trains[i].getFunctionMask() & 0x0F]);
|
||||||
@ -171,13 +315,7 @@ int trainDispatch(char* inBuffer, Serial* serial)
|
|||||||
uint8_t id = strtol(inBuffer, nullptr, 10);
|
uint8_t id = strtol(inBuffer, nullptr, 10);
|
||||||
if(id < trains.count() )
|
if(id < trains.count() )
|
||||||
{
|
{
|
||||||
if(powerIsOn == false)
|
setPower(true);
|
||||||
{
|
|
||||||
powerIsOn = true;
|
|
||||||
Train::setOutput(Train::LOW);
|
|
||||||
_delay_ms(100);
|
|
||||||
timer0InterruptEnable(true);
|
|
||||||
}
|
|
||||||
char* token = strtok(NULL, " ");
|
char* token = strtok(NULL, " ");
|
||||||
if( token != NULL && (strcmp(token, "speed") == 0 || strcmp(token, "s") == 0) )
|
if( token != NULL && (strcmp(token, "speed") == 0 || strcmp(token, "s") == 0) )
|
||||||
{
|
{
|
||||||
@ -203,7 +341,8 @@ int trainDispatch(char* inBuffer, Serial* serial)
|
|||||||
}
|
}
|
||||||
else if(token != NULL && strcmp(token, "probe") == 0 )
|
else if(token != NULL && strcmp(token, "probe") == 0 )
|
||||||
{
|
{
|
||||||
for(uint16_t j = 0; j < 1024; j++)
|
serial->flush();
|
||||||
|
for(uint16_t j = 0; j < 1024 && !serial->dataIsWaiting(); j++)
|
||||||
{
|
{
|
||||||
trains[id].sendRaw(j);
|
trains[id].sendRaw(j);
|
||||||
snprintf(buffer, SNPRINTF_BUFFER_SIZE, "TRYING: %x\n", j);
|
snprintf(buffer, SNPRINTF_BUFFER_SIZE, "TRYING: %x\n", j);
|
||||||
@ -213,6 +352,7 @@ int trainDispatch(char* inBuffer, Serial* serial)
|
|||||||
cli();
|
cli();
|
||||||
}
|
}
|
||||||
sei();
|
sei();
|
||||||
|
serial->flush();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if(token != NULL && strcmp(token, "raw") == 0 )
|
else if(token != NULL && strcmp(token, "raw") == 0 )
|
||||||
@ -245,12 +385,14 @@ int trainDispatch(char* inBuffer, Serial* serial)
|
|||||||
trains[id].stop();
|
trains[id].stop();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if( strcmp(inBuffer, "delete") == 0)
|
else if( token != NULL && strcmp(token, "delete") == 0)
|
||||||
{
|
{
|
||||||
trains.erase(id);
|
trains.erase(id);
|
||||||
serial->write_p(PSTR("Train: "));
|
serial->write_p(PSTR("Train: "));
|
||||||
serial->write(id);
|
serial->write(id);
|
||||||
serial->write_p(PSTR(" deleted\n"));
|
serial->write_p(PSTR(" deleted\n"));
|
||||||
|
save_state();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -271,9 +413,7 @@ int powerDispatch(char* token, Serial* serial)
|
|||||||
{
|
{
|
||||||
if(strcmp(token, "off") == 0)
|
if(strcmp(token, "off") == 0)
|
||||||
{
|
{
|
||||||
timer0InterruptEnable(false);
|
setPower(false);
|
||||||
Train::setOutput(Train::OFF);
|
|
||||||
powerIsOn = false;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if( strcmp(token, "on") == 0)
|
else if( strcmp(token, "on") == 0)
|
||||||
@ -282,8 +422,7 @@ int powerDispatch(char* token, Serial* serial)
|
|||||||
{
|
{
|
||||||
trains[i].setSpeed(0);
|
trains[i].setSpeed(0);
|
||||||
}
|
}
|
||||||
Train::setOutput(Train::LOW);
|
setPower(true);
|
||||||
timer0InterruptEnable(true);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if(strcmp(token, "auto") == 0)
|
else if(strcmp(token, "auto") == 0)
|
||||||
@ -322,12 +461,18 @@ void serialDispatch(Serial* serial)
|
|||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
char* token = strtok(buffer, " ");
|
char* token = strtok(buffer, " ");
|
||||||
if(length > 4 && (strcmp(token, "train") == 0 || strcmp(token, "t") == 0 ))
|
if(strcmp(token, "train") == 0 || strcmp(token, "t") == 0 )
|
||||||
{
|
{
|
||||||
token = strtok(NULL, " ");
|
token = strtok(NULL, " ");
|
||||||
if(token != NULL)
|
if(token != NULL)
|
||||||
ret = trainDispatch(token, serial);
|
ret = trainDispatch(token, serial);
|
||||||
}
|
}
|
||||||
|
else if(strcmp(token, "turnout") == 0)
|
||||||
|
{
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
if(token != NULL)
|
||||||
|
ret = turnoutDispatch(token, serial);
|
||||||
|
}
|
||||||
else if(strncmp(token, "erase", 4) == 0)
|
else if(strncmp(token, "erase", 4) == 0)
|
||||||
{
|
{
|
||||||
for(uint16_t i = 0; i < EPPROM_SIZE; i++) EEPROM_write_char(i, 0);
|
for(uint16_t i = 0; i < EPPROM_SIZE; i++) EEPROM_write_char(i, 0);
|
||||||
@ -420,17 +565,20 @@ int main()
|
|||||||
|
|
||||||
serial.write_p(PSTR("TrainController v0.5 starting\n"));
|
serial.write_p(PSTR("TrainController v0.5 starting\n"));
|
||||||
|
|
||||||
uint8_t trainToResend = 0;
|
uint8_t itemToResend = 0;
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
if(resendEvent && trains.count() > 0)
|
if(resendEvent && (trains.count() > 0 || turnouts.count()))
|
||||||
{
|
{
|
||||||
timer0InterruptEnable(false);
|
timer0InterruptEnable(false);
|
||||||
trains[trainToResend].sendData();
|
if(itemToResend < trains.count())
|
||||||
trainToResend++;
|
trains[itemToResend].sendData();
|
||||||
if(trains.count() <= trainToResend)
|
else if(itemToResend < trains.count() + turnouts.count())
|
||||||
trainToResend = 0;
|
turnouts[itemToResend-trains.count()].sendData();
|
||||||
|
itemToResend++;
|
||||||
|
if(trains.count()+turnouts.count() <= itemToResend)
|
||||||
|
itemToResend = 0;
|
||||||
resendEvent = false;
|
resendEvent = false;
|
||||||
timer0InterruptEnable(true);
|
timer0InterruptEnable(true);
|
||||||
}
|
}
|
||||||
|
38
turnout.cpp
Normal file
38
turnout.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#include "turnout.h"
|
||||||
|
|
||||||
|
Turnout::Turnout(uint8_t address, uint8_t subaddress): Item(address), _subaddress(subaddress)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Turnout::setDirection(uint8_t direction)
|
||||||
|
{
|
||||||
|
_direction = direction;
|
||||||
|
sendData();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Turnout::getDirection()
|
||||||
|
{
|
||||||
|
return _direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Turnout::getSubaddress()
|
||||||
|
{
|
||||||
|
return _subaddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Turnout::getPacket()
|
||||||
|
{
|
||||||
|
uint16_t data = 0;
|
||||||
|
data |= (_direction << 9) | (_direction << 8);
|
||||||
|
for (uint8_t i = 0; i < 2; ++i)
|
||||||
|
{
|
||||||
|
uint8_t bit = (_subaddress & (1 << i)) >> i;
|
||||||
|
data |= (bit << (7-i*2)) | (bit << (6-i*2));
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Turnout::sendData()
|
||||||
|
{
|
||||||
|
sendRaw(getPacket());
|
||||||
|
}
|
22
turnout.h
Normal file
22
turnout.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "item.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
class Turnout: public Item
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr uint8_t LEFT = 0;
|
||||||
|
static constexpr uint8_t RIGHT = 1;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t _direction = LEFT;
|
||||||
|
uint8_t _subaddress;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Turnout(uint8_t address, uint8_t subaddress);
|
||||||
|
void setDirection(uint8_t direction);
|
||||||
|
uint8_t getDirection();
|
||||||
|
uint8_t getSubaddress();
|
||||||
|
uint16_t getPacket();
|
||||||
|
void sendData();
|
||||||
|
};
|
Reference in New Issue
Block a user