I'm trying to get a number of Mega's to talk to each other using a packeting protocol I wrote.
I'm using multiple UARTs, and I would like to use the same functions to send and receive to and from all the ports.
To do this, I tried passing a pointer to a HardwareSerial class:
void Update(HardwareSerial * thisSerial=&Serial);
This doesn't seem to work (which doesn't really surprise me).
Can anyone tell me what the proper way to approach this problem would be?
That looks useful, but not clear to this non software guru.
You call the Update() function with no arguments, but the function definition has two arguments, WTF? Or is "HardwareSerial & thisSerial = Serial" not an argument(s), but rather some C++ magic concoction?
What changes would be needed in the example to use it on say hardware serial 3 port?
In this case you have two arguments (receive and transmit pin) which do not take defaults, and a third argument "inverse_logic" which defaults to false.
At least post something that ought to compile. ie. with setup, loop, the whole class, calling the class, using more than one serial port, etc. Not necessarily the whole project, but enough to demonstrate the thing you are trying to do.
Alright. The reason I was trying to avoid doing this because it's all over the place and there are other problems that I'm still working on (the rest compiles fine though), but here it is:
LinkedList.h:
#ifndef LinkedList_h
#define LinkedList_h
#include "Arduino.h"
template <class T>
class List{
public:
List();
void push(T data);//LIFO - pushes onto start
void queue(T data);//FIFO - adds on end
T pop();
T tail();
bool isEmpty();
uint8_t checksum8bit();
void insert(T data,T entrypoint);
void clear();
private:
struct node{
node *next,*prev;
T data;
};
node *_head,*_tail;
uint16_t _n;//number of elements
};
template <class T>
List<T>::List(){
_head=NULL;
_n=0;
}
template <class T>
void List<T>::push(T data){//pushes a new value to the front of the list
node * temp=new node;//give memory space
temp->data=data;//fill space
temp->next=_head;//connect to list
_head->prev=temp;
temp->prev=NULL;
_head=temp;//redefine start of list
if(isEmpty()){
_tail=temp;//first item added is both the tail and the head
}
_n++;
}
template <class T>
void List<T>::queue(T data){//queues a new value at the end of the list
node * temp=new node;//give memory space
temp->data=data;//fill space
temp->next=NULL;
temp->prev=_tail;
if(isEmpty()){
_head=temp;
}else{
_tail->next=temp;//put new value after current tail
}
_tail=temp;//new value is new tail
_n++;
}
template <class T>
T List<T>::pop(){//pops the head off the list
node *temp=_head;//pointer to allow deletion
T temp_data=_head->data;//data to return
_head=_head->next;//shift list along one
delete temp;//delete node before head
_n--;
return temp_data;//return data
}
template <class T>
T List<T>::tail(){//pops the head off the list
node *temp=_tail;//pointer to allow deletion
T temp_data=_tail->data;//data to return
_tail=_tail->prev;//shift list along one
delete temp;//delete node before head
_n--;
return temp_data;//return data
}
template <class T>
uint8_t List<T>::checksum8bit(){//returns 8-bit checksum of whole list
uint8_t checksum=0;
node * temp=_head;
while(temp->next!=NULL){//run through list
checksum+=temp->data;
temp=temp->next;//list should stay intact
}
return checksum;
}
template <class T>
bool List<T>::isEmpty(){
return _head == NULL;
}
template <class T>
void List<T>::clear(){
while(!isEmpty()){
pop();
}
}
#endif
SerialChain.h
#ifndef SerialNode_h
#define SerialNode_h
#include "Arduino.h"
#include "LinkedList.h"
#define START '['
#define STOP ']'
#define ESCAPE '\\'
struct Packet{
uint8_t address;
List <uint8_t> data;
uint8_t checksum;
};
class SerialNode{
public:
SerialNode(HardwareSerial & UART = Serial) : thisSerial (UART){}
void Update();
void SendPacket(uint8_t address,List <uint8_t> data);
private:
HardwareSerial & thisSerial;//UART of the node
List <uint8_t> buffer;//data buffer
void Clear();//clears received info
uint32_t _lastByte;//time of last inPacket
bool _isPacket;
bool _escaped;
uint8_t _checksum;
Packet inPacket;
};
SerialNode::SerialNode(HardwareSerial & UART = Serial){
}
void SerialNode::Update(){
if(thisSerial.available()>0){//only one value per iteration to prevent blocking
if(abs(_lastByte-millis())>1000){//if more than n millis pass after a packet, ditch data
Clear();
_isPacket=0;//no longer in a packet
}
uint8_t sbyte=thisSerial.read();//pop byte into variable
_lastByte=millis();//timestamp the byte
if(_isPacket){
if(!_escaped){
if(sbyte==START){//START byte but already in packet - strange
Clear();//but stay in packet
}else if(sbyte==ESCAPE){
_escaped=1;
}else if(sbyte==STOP){//pack up the packet
inPacket.checksum=buffer.tail();//pull checksum off the back of the list
_checksum=buffer.checksum8bit();//calculate checksum from remaining data
inPacket.address=buffer.pop();//read address from start of list
Serial.write(inPacket.checksum);
if(inPacket.checksum==_checksum){
//RETURN SUCCESS
Clear();
}else{
//RETURN FAILED
Clear();//delete data
}
inPacket.data=buffer;
_isPacket=0;
}else{//normal character that is part of a packet
buffer.queue(sbyte);
}
}else if(sbyte==START||sbyte==STOP||sbyte==ESCAPE){//escape should be followed by a forbidden character
buffer.queue(sbyte);
_escaped=0;
}else{//pointless escape character - ignore - packet will probably error out
_escaped=0;
}
}else if(sbyte==START){
_isPacket=1;
}
//any data not START or in a packet gets ignored
}
}
void SerialNode::Clear(){//clear space
inPacket.address=0;
inPacket.data.clear();
inPacket.checksum=0;
}
void SerialNode::SendPacket(uint8_t address,List <uint8_t> data){
thisSerial.write(START);//start packet
thisSerial.write(address);//send address
uint8_t pbyte;
uint8_t checksum=data.checksum8bit();
while(!data.isEmpty()){
pbyte=data.pop();
if(pbyte==START||pbyte==STOP||pbyte==ESCAPE){
thisSerial.write(ESCAPE);//escape character out if necessary
}
thisSerial.write(pbyte);//write data byte
}
thisSerial.write(checksum);
thisSerial.write(STOP);
}
#endif
In file included from serialchaintest2.ino:1:0:
/home/scott/sketchbook/libraries/SerialChain/SerialChain.h:23:20: warning: ignoring packed attribute because of unpacked non-POD field ‘HardwareSerial& SerialNode::thisSerial’ [enabled by default]
/home/scott/sketchbook/libraries/SerialChain/SerialChain.h:33:1: error: redefinition of ‘SerialNode::SerialNode(HardwareSerial&)’
/home/scott/sketchbook/libraries/SerialChain/SerialChain.h:19:3: error: ‘SerialNode::SerialNode(HardwareSerial&)’ previously defined here
make: *** [serialchaintest2.o] Error 1