Split train class into item and train
Use SVector to store trains
This commit is contained in:
		
							parent
							
								
									86c36f7a21
								
							
						
					
					
						commit
						0b528fbf1e
					
				
					 7 changed files with 285 additions and 187 deletions
				
			
		| 
						 | 
					@ -17,9 +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 own source files
 | 
					set(SRC_FILES  main.cpp serial.cpp  train.cpp item.cpp)
 | 
				
			||||||
# Simply list all your C / C++ source (not header!) files here
 | 
					 | 
				
			||||||
set(SRC_FILES  main.cpp serial.cpp  train.cpp)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Compiler suite specification
 | 
					# Compiler suite specification
 | 
				
			||||||
set(CMAKE_C_COMPILER /usr/bin/avr-gcc)
 | 
					set(CMAKE_C_COMPILER /usr/bin/avr-gcc)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										93
									
								
								item.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								item.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,93 @@
 | 
				
			||||||
 | 
					#include "item.h"
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static volatile unsigned char *_port = &PORTD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Item::Item(const uint8_t address):  _address(address)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Item::setAddress(const uint8_t address)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _address = address;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t Item::getAddress()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return _address;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Item::off()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    writePin(_port, _pinHighA, false);
 | 
				
			||||||
 | 
					    writePin(_port, _pinHighB, false);
 | 
				
			||||||
 | 
					    writePin(_port, _pinLowA,  true);
 | 
				
			||||||
 | 
					    writePin(_port, _pinLowB,  true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Item::setOutput(const uint8_t state)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(state == HIGH)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        off();
 | 
				
			||||||
 | 
					        _delay_us(3);
 | 
				
			||||||
 | 
					        writePin(_port, _pinHighA, true);
 | 
				
			||||||
 | 
					        writePin(_port, _pinLowB,  false);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (state == LOW)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        off();
 | 
				
			||||||
 | 
					        _delay_us(3);
 | 
				
			||||||
 | 
					        writePin(_port, _pinHighB, true);
 | 
				
			||||||
 | 
					        writePin(_port, _pinLowA,  false);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        off();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Item::sendBit(const bool bit)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(bit)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setOutput(HIGH);
 | 
				
			||||||
 | 
					        _delay_us(170);
 | 
				
			||||||
 | 
					        setOutput(LOW);
 | 
				
			||||||
 | 
					        _delay_us(25);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setOutput(HIGH);
 | 
				
			||||||
 | 
					        _delay_us(20);
 | 
				
			||||||
 | 
					        setOutput(LOW);
 | 
				
			||||||
 | 
					        _delay_us(175);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Item::sendAddress(uint8_t address)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for(uint8_t i = 0; i < 8; i++) 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sendBit(address & (1 << i));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Item::sendRawAddr(const uint16_t address, const uint16_t data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    for(uint8_t j = 0; j < SEND_COUNT; j++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sendAddress(address);
 | 
				
			||||||
 | 
					        for(uint8_t i = 0; i < 10; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            sendBit(data & (1 << i));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        _delay_ms(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Item::sendRaw(const uint16_t data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    sendRawAddr(_address, data);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										46
									
								
								item.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								item.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,46 @@
 | 
				
			||||||
 | 
					#include "writepin.h"
 | 
				
			||||||
 | 
					#include <util/delay.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					#include <avr/io.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Item
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    static constexpr uint8_t HIGH = 2;
 | 
				
			||||||
 | 
					    static constexpr uint8_t LOW = 1;
 | 
				
			||||||
 | 
					    static constexpr uint8_t OFF = 0;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    static constexpr unsigned char _pinHighA = PD5;
 | 
				
			||||||
 | 
					    static constexpr unsigned char _pinLowA = PD4;
 | 
				
			||||||
 | 
					    static constexpr unsigned char _pinHighB = PD2;
 | 
				
			||||||
 | 
					    static constexpr unsigned char _pinLowB = PD3;
 | 
				
			||||||
 | 
					    static constexpr uint8_t SEND_COUNT = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t _address;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline static void off();
 | 
				
			||||||
 | 
					    static void sendBit(const bool bit);
 | 
				
			||||||
 | 
					    static void sendAddress(uint8_t address);
 | 
				
			||||||
 | 
					    uint16_t packetAddSpeed();
 | 
				
			||||||
 | 
					    uint16_t packetAddDirection();
 | 
				
			||||||
 | 
					    uint16_t packetAddFunction(const uint8_t function);
 | 
				
			||||||
 | 
					    uint16_t assemblePacket();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    static void setOutput(const uint8_t state);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Item(const uint8_t address);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    void sendRaw(const uint16_t data);
 | 
				
			||||||
 | 
					    static void sendRawAddr(const uint16_t address, const uint16_t data);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						void setAddress(const uint8_t address);
 | 
				
			||||||
 | 
						uint8_t getAddress();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										77
									
								
								main.cpp
									
										
									
									
									
								
							
							
						
						
									
										77
									
								
								main.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -9,16 +9,15 @@
 | 
				
			||||||
#include "eeprom.h"
 | 
					#include "eeprom.h"
 | 
				
			||||||
#include "bitrep.h"
 | 
					#include "bitrep.h"
 | 
				
			||||||
#include "ringbuffer.h"
 | 
					#include "ringbuffer.h"
 | 
				
			||||||
 | 
					#include "staticvector.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MAX_TRAINS 16
 | 
					 | 
				
			||||||
#define COMMAND_BUFFER_SIZE 64
 | 
					#define COMMAND_BUFFER_SIZE 64
 | 
				
			||||||
#define SNPRINTF_BUFFER_SIZE 128
 | 
					#define SNPRINTF_BUFFER_SIZE 128
 | 
				
			||||||
#define EPPROM_SIZE 1024
 | 
					#define EPPROM_SIZE 1024
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char buffer[SNPRINTF_BUFFER_SIZE];
 | 
					char buffer[SNPRINTF_BUFFER_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t storedTrains = 0;
 | 
					SVector<Train, 16> trains;
 | 
				
			||||||
Train trains[MAX_TRAINS];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool autoff = true;
 | 
					bool autoff = true;
 | 
				
			||||||
bool powerIsOn = true;
 | 
					bool powerIsOn = true;
 | 
				
			||||||
| 
						 | 
					@ -54,9 +53,9 @@ void timer0InterruptEnable(const bool enable)
 | 
				
			||||||
void save_state()
 | 
					void save_state()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	cli();
 | 
						cli();
 | 
				
			||||||
	EEPROM_write_char( 0, storedTrains );
 | 
						EEPROM_write_char( 0, trains.count() );
 | 
				
			||||||
	EEPROM_write_char( 1, autoff );
 | 
						EEPROM_write_char( 1, autoff );
 | 
				
			||||||
	for(uint16_t i = 0; i < storedTrains; 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());
 | 
				
			||||||
| 
						 | 
					@ -66,17 +65,19 @@ void save_state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void restore_state()
 | 
					void restore_state()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	storedTrains = EEPROM_read_char(0);
 | 
						uint8_t trainCount = EEPROM_read_char(0);
 | 
				
			||||||
	autoff = EEPROM_read_char(1);
 | 
						autoff = EEPROM_read_char(1);
 | 
				
			||||||
	if(storedTrains > MAX_TRAINS ) 
 | 
						
 | 
				
			||||||
 | 
						trains.clear();
 | 
				
			||||||
 | 
						if(trainCount > trains.maxSize() ) 
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		for(uint16_t i = 0; i < EPPROM_SIZE; i++) EEPROM_write_char(i, 0);
 | 
							for(uint16_t i = 0; i < EPPROM_SIZE; i++)
 | 
				
			||||||
		storedTrains = 0;
 | 
								EEPROM_write_char(i, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else for(uint8_t i = 0; i < storedTrains; i++)
 | 
						else 
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		trains[i].setAddress(EEPROM_read_char(32+i*2)); 
 | 
							for(uint8_t i = 0; i < trainCount; i++)
 | 
				
			||||||
		trains[i].setFunctionMask(EEPROM_read_char(32+1+i*2));
 | 
								trains.push_back(Train(EEPROM_read_char(32+i*2), EEPROM_read_char(32+1+i*2)));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -108,42 +109,32 @@ int trainDispatch(char* inBuffer, Serial* serial)
 | 
				
			||||||
		uint8_t address = 0;
 | 
							uint8_t address = 0;
 | 
				
			||||||
		if(token != NULL)
 | 
							if(token != NULL)
 | 
				
			||||||
			address = strtol(token, nullptr, 10);
 | 
								address = strtol(token, nullptr, 10);
 | 
				
			||||||
		if(address != 0 && storedTrains < MAX_TRAINS) 
 | 
							if(address != 0 && trains.remainingCapacity() > 0) 
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			trains[storedTrains].setAddress(address);
 | 
								uint8_t functionMask = 0;
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			token = strtok(NULL, " ");
 | 
								token = strtok(NULL, " ");
 | 
				
			||||||
			if(token != NULL) 
 | 
								if(token != NULL) 
 | 
				
			||||||
				trains[storedTrains].setFunctionMask(strtol(token, nullptr, 2 ));
 | 
									functionMask = strtol(token, nullptr, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								trains.push_back(Train(address, functionMask));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			uint8_t size = snprintf(buffer, SNPRINTF_BUFFER_SIZE, "TRAIN saved! NUMBER: %u ADDRESS: %u FUNCTIONS: %s FUNCTIONMASK: %s\n", 
 | 
								uint8_t size = snprintf(buffer, SNPRINTF_BUFFER_SIZE, "TRAIN saved! NUMBER: %u ADDRESS: %u FUNCTIONS: %s FUNCTIONMASK: %s\n", 
 | 
				
			||||||
									storedTrains,
 | 
														trains.count(),
 | 
				
			||||||
									address,
 | 
														address,
 | 
				
			||||||
									bit_rep[trains[storedTrains].getFunctions() & 0x0F],
 | 
														bit_rep[trains.back().getFunctions() & 0x0F],
 | 
				
			||||||
									bit_rep[trains[storedTrains].getFunctionMask() & 0x0F]);
 | 
														bit_rep[trains.back().getFunctionMask() & 0x0F]);
 | 
				
			||||||
			serial->write(buffer, size);
 | 
								serial->write(buffer, size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			storedTrains++;
 | 
					 | 
				
			||||||
			save_state();
 | 
								save_state();
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		serial->write_p(PSTR("Usage: train add [address] [functionmask]"));
 | 
							serial->write_p(PSTR("Usage: train add [address] [functionmask]"));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if( strcmp(inBuffer, "delete") == 0)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		serial->write_p(PSTR("Train: "));
 | 
					 | 
				
			||||||
		serial->write(storedTrains-1);
 | 
					 | 
				
			||||||
		serial->write_p(PSTR(" deleted\n"));
 | 
					 | 
				
			||||||
		storedTrains--;
 | 
					 | 
				
			||||||
		if(storedTrains < 0)
 | 
					 | 
				
			||||||
			storedTrains = 0;
 | 
					 | 
				
			||||||
		save_state();
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else if( strcmp(inBuffer, "list") == 0 )
 | 
						else if( strcmp(inBuffer, "list") == 0 )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		serial->write_p(PSTR("Trains:\n"));
 | 
							serial->write_p(PSTR("Trains:\n"));
 | 
				
			||||||
		for(uint8_t i = 0; i < storedTrains; 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 ID: %u CURRENT PACKET: %x SPEED: %i FUNCTIONS: %s FUNCTIONMASK: %s\n", 
 | 
				
			||||||
						i, trains[i].getAddress(),
 | 
											i, trains[i].getAddress(),
 | 
				
			||||||
| 
						 | 
					@ -178,7 +169,7 @@ int trainDispatch(char* inBuffer, Serial* serial)
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		uint8_t id = strtol(inBuffer, nullptr, 10);
 | 
							uint8_t id = strtol(inBuffer, nullptr, 10);
 | 
				
			||||||
		if(id < storedTrains )
 | 
							if(id < trains.count() )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if(powerIsOn == false)
 | 
								if(powerIsOn == false)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
| 
						 | 
					@ -233,7 +224,7 @@ int trainDispatch(char* inBuffer, Serial* serial)
 | 
				
			||||||
					uint16_t i = strtol(token, nullptr, 16 );
 | 
										uint16_t i = strtol(token, nullptr, 16 );
 | 
				
			||||||
					snprintf(buffer, SNPRINTF_BUFFER_SIZE, "SENDING: %x to %x\n", i, trains[id].getAddress());
 | 
										snprintf(buffer, SNPRINTF_BUFFER_SIZE, "SENDING: %x to %x\n", i, trains[id].getAddress());
 | 
				
			||||||
					serial->write(buffer, strlen(buffer));
 | 
										serial->write(buffer, strlen(buffer));
 | 
				
			||||||
					//for(uint8_t j = 0; j < 100; j++)
 | 
										for(uint8_t j = 0; j < 100; j++)
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						trains[id].sendRaw(i);
 | 
											trains[id].sendRaw(i);
 | 
				
			||||||
						_delay_ms(20);
 | 
											_delay_ms(20);
 | 
				
			||||||
| 
						 | 
					@ -254,6 +245,13 @@ int trainDispatch(char* inBuffer, Serial* serial)
 | 
				
			||||||
				trains[id].stop();
 | 
									trains[id].stop();
 | 
				
			||||||
				return 0;
 | 
									return 0;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								else if( strcmp(inBuffer, "delete") == 0)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									trains.erase(id);
 | 
				
			||||||
 | 
									serial->write_p(PSTR("Train: "));
 | 
				
			||||||
 | 
									serial->write(id);
 | 
				
			||||||
 | 
									serial->write_p(PSTR(" deleted\n"));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			else 
 | 
								else 
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				serial->write_p(PSTR("Not a valid command\n"));
 | 
									serial->write_p(PSTR("Not a valid command\n"));
 | 
				
			||||||
| 
						 | 
					@ -280,7 +278,7 @@ int powerDispatch(char* token, Serial* serial)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else if( strcmp(token, "on") == 0)
 | 
						else if( strcmp(token, "on") == 0)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		for(uint16_t i = 0; i < storedTrains; i++)
 | 
							for(uint16_t i = 0; i < trains.count(); i++)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			trains[i].setSpeed(0);
 | 
								trains[i].setSpeed(0);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -334,7 +332,7 @@ void serialDispatch(Serial* serial)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				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);
 | 
				
			||||||
				serial->write_p(PSTR("EEPROM erased\n"));
 | 
									serial->write_p(PSTR("EEPROM erased\n"));
 | 
				
			||||||
				storedTrains = 0;
 | 
									trains.clear();
 | 
				
			||||||
				ret = 0;
 | 
									ret = 0;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else if(strcmp(token, "dump") == 0)
 | 
								else if(strcmp(token, "dump") == 0)
 | 
				
			||||||
| 
						 | 
					@ -349,7 +347,7 @@ void serialDispatch(Serial* serial)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else if((strcmp(token, "stop") == 0 || strcmp(token, "s") == 0 ))
 | 
								else if((strcmp(token, "stop") == 0 || strcmp(token, "s") == 0 ))
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				for(uint16_t i = 0; i < storedTrains; i++)
 | 
									for(uint16_t i = 0; i < trains.count(); i++)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					cli();
 | 
										cli();
 | 
				
			||||||
					trains[i].stop();
 | 
										trains[i].stop();
 | 
				
			||||||
| 
						 | 
					@ -426,13 +424,12 @@ int main()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while(true)
 | 
						while(true)
 | 
				
			||||||
	{        
 | 
						{        
 | 
				
			||||||
		if(resendEvent && storedTrains > 0) 
 | 
							if(resendEvent && trains.count() > 0) 
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			//_delay_ms(100);
 | 
					 | 
				
			||||||
			timer0InterruptEnable(false);
 | 
								timer0InterruptEnable(false);
 | 
				
			||||||
			trains[trainToResend].sendData();
 | 
								trains[trainToResend].sendData();
 | 
				
			||||||
			trainToResend++;
 | 
								trainToResend++;
 | 
				
			||||||
			if(storedTrains <= trainToResend)
 | 
								if(trains.count() <= trainToResend)
 | 
				
			||||||
				trainToResend = 0;
 | 
									trainToResend = 0;
 | 
				
			||||||
			resendEvent = false;
 | 
								resendEvent = false;
 | 
				
			||||||
			timer0InterruptEnable(true);
 | 
								timer0InterruptEnable(true);
 | 
				
			||||||
| 
						 | 
					@ -441,7 +438,7 @@ int main()
 | 
				
			||||||
		if(autoff) 
 | 
							if(autoff) 
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			bool trainsRunning = false;
 | 
								bool trainsRunning = false;
 | 
				
			||||||
			for(uint16_t i = 0; i < storedTrains; i++)
 | 
								for(uint16_t i = 0; i < trains.count(); i++)
 | 
				
			||||||
				trainsRunning = trainsRunning || trains[i].isActive();
 | 
									trainsRunning = trainsRunning || trains[i].isActive();
 | 
				
			||||||
			if(!trainsRunning)
 | 
								if(!trainsRunning)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										88
									
								
								staticvector.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								staticvector.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,88 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T, size_t size> class SVector
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    size_t stored = 0;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
						char buff[sizeof(T)*size];
 | 
				
			||||||
 | 
						T *array = (T*)buff;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    T* data()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    T& operator[](size_t i)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    T& at(size_t i)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    T& front()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array[0];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    T& back()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array[stored-1];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    bool empty() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return stored == 0 ? true : false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    size_t count() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return stored;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    constexpr size_t maxSize() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return size;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    size_t remainingCapacity() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return size - stored;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    bool push_back(const T in)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if( remainingCapacity() != 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            array[stored] = in;
 | 
				
			||||||
 | 
					            ++stored;
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    bool erase(size_t position)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					       if(position > stored)
 | 
				
			||||||
 | 
							   return false;
 | 
				
			||||||
 | 
					       array[position].~T();
 | 
				
			||||||
 | 
					       --stored;
 | 
				
			||||||
 | 
					       for( size_t i = position; i < stored; i++ )
 | 
				
			||||||
 | 
							   memcpy(&array[i], &array[i+1], sizeof(T));
 | 
				
			||||||
 | 
					       return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    void clear()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
							for( size_t i = 0; i < stored; i++ )
 | 
				
			||||||
 | 
								array[i].~T();
 | 
				
			||||||
 | 
					        stored = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										115
									
								
								train.cpp
									
										
									
									
									
								
							
							
						
						
									
										115
									
								
								train.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -1,109 +1,10 @@
 | 
				
			||||||
#include "train.h"
 | 
					#include "train.h"
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static volatile unsigned char *_port = &PORTD;
 | 
					Train::Train(const uint8_t address, uint8_t functionmask):  Item(address), _functionmask(functionmask)
 | 
				
			||||||
 | 
					 | 
				
			||||||
Train::Train(const uint8_t address, uint8_t functionmask):  _address(address), _functionmask(functionmask)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Train::Train()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    _address = 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Train::setAddress(const uint8_t address)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    _address = address;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint8_t Train::getAddress()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return _address;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Train::stop()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    _speed = 0;
 | 
					 | 
				
			||||||
    _function = 0;
 | 
					 | 
				
			||||||
    sendData();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Train::off()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    writePin(_port, _pinHighA, false);
 | 
					 | 
				
			||||||
    writePin(_port, _pinHighB, false);
 | 
					 | 
				
			||||||
    writePin(_port, _pinLowA,  true);
 | 
					 | 
				
			||||||
    writePin(_port, _pinLowB,  true);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Train::setOutput(const uint8_t state)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if(state == HIGH)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        off();
 | 
					 | 
				
			||||||
        _delay_us(3);
 | 
					 | 
				
			||||||
        writePin(_port, _pinHighA, true);
 | 
					 | 
				
			||||||
        writePin(_port, _pinLowB,  false);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else if (state == LOW)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        off();
 | 
					 | 
				
			||||||
        _delay_us(3);
 | 
					 | 
				
			||||||
        writePin(_port, _pinHighB, true);
 | 
					 | 
				
			||||||
        writePin(_port, _pinLowA,  false);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        off();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Train::sendBit(const bool bit)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if(bit)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        setOutput(HIGH);
 | 
					 | 
				
			||||||
        _delay_us(170);
 | 
					 | 
				
			||||||
        setOutput(LOW);
 | 
					 | 
				
			||||||
        _delay_us(25);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        setOutput(HIGH);
 | 
					 | 
				
			||||||
        _delay_us(20);
 | 
					 | 
				
			||||||
        setOutput(LOW);
 | 
					 | 
				
			||||||
        _delay_us(175);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Train::sendAddress(uint8_t address)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    for(uint8_t i = 0; i < 8; i++) 
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        sendBit(address & (1 << i));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Train::sendRawAddr(const uint16_t address, const uint16_t data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    for(uint8_t j = 0; j < SEND_COUNT; j++)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        sendAddress(address);
 | 
					 | 
				
			||||||
        for(uint8_t i = 0; i < 10; i++)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            sendBit(data & (1 << i));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        _delay_ms(1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Train::sendRaw(const uint16_t data)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    sendRawAddr(_address, data);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uint16_t Train::packetAddSpeed()
 | 
					uint16_t Train::packetAddSpeed()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint16_t packet = 0;
 | 
					    uint16_t packet = 0;
 | 
				
			||||||
| 
						 | 
					@ -181,7 +82,15 @@ uint8_t Train::getSpeed()
 | 
				
			||||||
    return _speed;
 | 
					    return _speed;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t Train::assemblePacket()
 | 
					void Train::stop()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _speed = 0;
 | 
				
			||||||
 | 
					    _function = 0;
 | 
				
			||||||
 | 
					    sendData();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t Train::assembleSpeedPacket()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint16_t packet = packetAddSpeed() | packetAddFunction(0) | packetAddDirection();
 | 
					    uint16_t packet = packetAddSpeed() | packetAddFunction(0) | packetAddDirection();
 | 
				
			||||||
    return packet;
 | 
					    return packet;
 | 
				
			||||||
| 
						 | 
					@ -189,7 +98,7 @@ uint16_t Train::assemblePacket()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Train::sendData()
 | 
					void Train::sendData()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    sendRaw(assemblePacket());
 | 
					    sendRaw(assembleSpeedPacket());
 | 
				
			||||||
	if(_functionmask)
 | 
						if(_functionmask)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		uint8_t functionToResend = (_function & 0xF0) >> 4;
 | 
							uint8_t functionToResend = (_function & 0xF0) >> 4;
 | 
				
			||||||
| 
						 | 
					@ -208,7 +117,7 @@ void Train::sendData()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint16_t Train::getLastPacket()
 | 
					uint16_t Train::getLastPacket()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return assemblePacket();
 | 
					    return assembleSpeedPacket();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Train::reverse()
 | 
					void Train::reverse()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										43
									
								
								train.h
									
										
									
									
									
								
							
							
						
						
									
										43
									
								
								train.h
									
										
									
									
									
								
							| 
						 | 
					@ -1,47 +1,23 @@
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "writepin.h"
 | 
					#include "item.h"
 | 
				
			||||||
#include <util/delay.h>
 | 
					 | 
				
			||||||
#include <stdint.h>
 | 
					 | 
				
			||||||
#include <avr/io.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Train
 | 
					class Train: public Item
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    static constexpr uint8_t HIGH = 2;
 | 
					 | 
				
			||||||
    static constexpr uint8_t LOW = 1;
 | 
					 | 
				
			||||||
    static constexpr uint8_t OFF = 0;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    
 | 
						uint8_t _function = 0;
 | 
				
			||||||
    static constexpr unsigned char _pinHighA = PD5;
 | 
					 | 
				
			||||||
    static constexpr unsigned char _pinLowA = PD4;
 | 
					 | 
				
			||||||
    static constexpr unsigned char _pinHighB = PD2;
 | 
					 | 
				
			||||||
    static constexpr unsigned char _pinLowB = PD3;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    uint8_t _address;
 | 
					 | 
				
			||||||
    uint8_t _function = 0;
 | 
					 | 
				
			||||||
    uint8_t _functionmask;
 | 
					    uint8_t _functionmask;
 | 
				
			||||||
    uint8_t _speed = 0;
 | 
					    uint8_t _speed = 0;
 | 
				
			||||||
    bool _direction = false;
 | 
					    bool _direction = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const uint8_t SEND_COUNT = 2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    inline static void off();
 | 
					 | 
				
			||||||
    static void sendBit(const bool bit);
 | 
					 | 
				
			||||||
    static void sendAddress(uint8_t address);
 | 
					 | 
				
			||||||
    uint16_t packetAddSpeed();
 | 
					    uint16_t packetAddSpeed();
 | 
				
			||||||
    uint16_t packetAddDirection();
 | 
					    uint16_t packetAddDirection();
 | 
				
			||||||
    uint16_t packetAddFunction(const uint8_t function);
 | 
					    uint16_t packetAddFunction(const uint8_t function);
 | 
				
			||||||
    uint16_t assemblePacket();
 | 
					    uint16_t assembleSpeedPacket();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    static void setOutput(const uint8_t state);
 | 
					    Train(const uint8_t address, uint8_t functionmask = 0b0000);
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    Train(const uint8_t address, uint8_t functionmask = 0b1111);
 | 
					 | 
				
			||||||
    Train();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void sendData();
 | 
					    void sendData();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -51,8 +27,6 @@ public:
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    bool isActive() {return getSpeed() || getFunctions();}
 | 
					    bool isActive() {return getSpeed() || getFunctions();}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    uint8_t getAddress();
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    uint16_t getLastPacket();
 | 
					    uint16_t getLastPacket();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    void setSpeed(uint8_t speed);
 | 
					    void setSpeed(uint8_t speed);
 | 
				
			||||||
| 
						 | 
					@ -65,12 +39,5 @@ public:
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    uint8_t getFunctionMask();
 | 
					    uint8_t getFunctionMask();
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    void setAddress(const uint8_t address);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    void sendFunction(const uint8_t function, bool enable = true);
 | 
					    void sendFunction(const uint8_t function, bool enable = true);
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    void sendRaw(const uint16_t data);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    static void sendRawAddr(const uint16_t address, const uint16_t data);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue