SoftwareSerial and Ethernet (UDP) 'hang' [solved]
my eventual goal of project store real-time(ish) energy usage data graphing purposes. far i've got of individual elements of program down.
1) read out p1 port of dutch 'smart' meter. works quite well.
2) time data using 'time' library http://playground.arduino.cc/code/time. works amazingly easy.
3) store data somewhere (haven't decided on sd or ftp)
while both elements 1 , 2 work brilliantly apart each other, when combine them, weird happens. think there's conflict between functions of softwareserial library , ethernet library. right now, i've 'commented' 5 lines in setup(), , 1 in loop(), , works. however, when uncomment first line:
the serial connection p1 port of meter never available; it's 0.
does understand what's going wrong here? these 2 libraries incompatible or something?
the code:
1) read out p1 port of dutch 'smart' meter. works quite well.
2) time data using 'time' library http://playground.arduino.cc/code/time. works amazingly easy.
3) store data somewhere (haven't decided on sd or ftp)
while both elements 1 , 2 work brilliantly apart each other, when combine them, weird happens. think there's conflict between functions of softwareserial library , ethernet library. right now, i've 'commented' 5 lines in setup(), , 1 in loop(), , works. however, when uncomment first line:
code: [select]
ethernet.begin(mac);
the serial connection p1 port of meter never available; it's 0.
does understand what's going wrong here? these 2 libraries incompatible or something?
the code:
code: [select]
#include <spi.h> // sd, think; ethernet ntp sync example works without one.
#include <softwareserial.h>
#include <time.h> // time sync
#include <ethernet.h> // ntp service
#include <ethernetudp.h>
// p1
const byte requestpin = 3; // request pin
int incomingbyte = 0;
string inputstring = ""; // reading buffer
unsigned int typeindex[5]; // index of type identifier
const char startdelim = '('; // values start symbol
const char enddelims[5] = {'*','*',')','*',')'}; // values end symbol
// ethernet
byte mac[] = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed };
unsigned int localport = 8888; // local port listen udp packets
// ntp
ipaddress timeserver(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov
const int timezone = 1; // no dst
// general
string vals; // value storage
// start crap
softwareserial p_one(10, 11, true); // rx, tx, inverted
ethernetudp udp;
void setup () {
p_one.begin(9600);
delay(10);
serial.begin(9600);
pinmode(requestpin, output);
digitalwrite(requestpin, high);
//ethernet.begin(mac); // if uncomment line, p_one.available() starts out full buffer, 0 on
//serial.print("ip assigned: "); serial.println(ethernet.localip());
//udp.begin(localport);
//setsyncprovider(getntptime);
//while(timestatus() == timenotset); // wait until time sync
}
void loop () {
while (p_one.available()) {
incomingbyte = p_one.read();
incomingbyte &= ~(1 << 7);
char inchar = (char)incomingbyte;
inputstring += inchar;
if (inchar == '!'){ // data dump end symbol
serial.println(inputstring);
if (inputstring.length() == 453) { // data dump must specific size.
//storetime();
findindices();
findvals();
storevals();
vals = "";
}
inputstring = ""; // reset inputstring next reading
}
}
}
void storevals(){
// store values either sd card, or ftp server. whichever work first.
}
void findindices(){
// finds indices of headers
typeindex[0] = inputstring.indexof("1.8.1")+4;
typeindex[1] = inputstring.indexof("1.8.2")+4;
typeindex[2] = inputstring.indexof("96.14.0")+4;
typeindex[3] = inputstring.indexof("1.7.0")+4;
typeindex[4] = inputstring.indexof("24.2.1")+11;
}
void findvals(){
// find actual values, , puts them in 'vals'
unsigned int indices[2];
for(byte x = 0; x < 5; x++){
indices[1] = inputstring.indexof(startdelim,typeindex[x])+1; // find value location
indices[2] = inputstring.indexof(enddelims[x],typeindex[x]); // place value in array
vals += inputstring.substring(indices[1], indices[2]);
if(x < 4){vals += ",";}
}
serial.println("vals: "+vals+"\n");
}
void storetime(){
// time library should automatically sync time
vals += string(hour())+':';
if (minute()<10) vals += '0';
vals += string(minute())+':';
if (second()<10) vals += '0';
vals += string(second());
vals += ",";
vals += string(day())+'/'+string(month())+'/'+string(year());
}
/*-------- ntp code ----------*/
const int ntp_packet_size = 48; // ntp time in first 48 bytes of message
byte packetbuffer[ntp_packet_size]; //buffer hold incoming & outgoing packets
time_t getntptime(){
while (udp.parsepacket() > 0) ; // discard received packets
serial.println("transmit ntp request");
sendntppacket(timeserver);
uint32_t beginwait = millis();
while (millis() - beginwait < 1500) {
int size = udp.parsepacket();
if (size >= ntp_packet_size) {
serial.println("ntp response");
udp.read(packetbuffer, ntp_packet_size); // read packet buffer
unsigned long secssince1900;
// convert 4 bytes starting @ location 40 long integer
secssince1900 = (unsigned long)packetbuffer[40] << 24;
secssince1900 |= (unsigned long)packetbuffer[41] << 16;
secssince1900 |= (unsigned long)packetbuffer[42] << 8;
secssince1900 |= (unsigned long)packetbuffer[43];
return secssince1900 - 2208988800ul + timezone * secs_per_hour;
}
}
serial.println("no ntp response :-(");
return 0; // return 0 if unable time
}
// send ntp request time server @ given address
void sendntppacket(ipaddress &address){
// set bytes in buffer 0
memset(packetbuffer, 0, ntp_packet_size);
// initialize values needed form ntp request
// (see url above details on packets)
packetbuffer[0] = 0b11100011; // li, version, mode
packetbuffer[1] = 0; // stratum, or type of clock
packetbuffer[2] = 6; // polling interval
packetbuffer[3] = 0xec; // peer clock precision
// 8 bytes of 0 root delay & root dispersion
packetbuffer[12] = 49;
packetbuffer[13] = 0x4e;
packetbuffer[14] = 49;
packetbuffer[15] = 52;
// ntp fields have been given values now
// can send packet requesting timestamp:
udp.beginpacket(address, 123); //ntp requests port 123
udp.write(packetbuffer, ntp_packet_size);
udp.endpacket();
}
you can't use d10-d13 softwareserial pins. used spi. how ethernet shield communicates arduino. since using softwareserial, presume uno, try d8 , d9 rx/tx pins instead.
Arduino Forum > Using Arduino > Programming Questions > SoftwareSerial and Ethernet (UDP) 'hang' [solved]
arduino
Comments
Post a Comment