Quello che segue è il codice per arduino e per un po' funziona, anche se non sempre la stringa è corretta: a volte mancano i primi due campi.
La fine della stringa però dovrei prenderla giusta, con il carattere ascii 13
Devo ancora vedere meglio come leggere da seriale, ma poichè il pin rx di arduino è condiviso con l'usb con cui lo programmo e debuggo non è facile. E per di più devo fare due rampe di scale dopo ogni correzione.
A parte questo, i dati su mysql, almeno per un po', li sta salvando.
Dovrebbe anche salvarli sulla microSD, ma ho ancora qualche problema (anche se riesco a scrivere correttamente sulla scheda).
All'avvio si sincronizza via ntp con il server dell'ora, e usa l'ora interna per creare il record sul file csv nella SD
/*
Save Rotex RSP3 data to SD card and mysql database
Use NTP time provider to sync internal time
*/
#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>
#include <SD.h>
#include <Time.h>
// Network stuff
byte mac[] = {
0x90, 0xA2, 0xDA, 0x00, 0x66, 0x38 }; //Arduino MAC address
byte ip[] = {
192,168,1,177 }; //Arduino IP address
byte gateway[] = {
192,168,1,250 }; //Network gateway
byte mask[] = {
255,255,255,0 }; //Network netmask
// NTP stuff
unsigned int localPort = 8888; // local port to listen for UDP packets
byte timeServer[] = {
192, 43, 244, 18 }; //NTP server address
const int NTP_PACKET_SIZE= 48; // NTP time stamp
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
const long timeZoneOffset = 3600; // set this to the offset in seconds to your local time;
// Web client stuff
byte server[] = {
192,168,12,8 }; //Web server address
//Client client(server, 82); //ip,port (usually 80)
// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 4;
boolean SDpresent=false;
#define STRINGTERMINATOR 13 //define end of string
#define BUFFERSIZE 30 //max string lenght
char ReadBuffer[BUFFERSIZE+1]; //Add 1 for NULL terminator
void setup(){
// start Ethernet and UDP
Ethernet.begin(mac, ip, gateway, mask);
Udp.begin(localPort);
//start serial
Serial.begin(9600);
//start SD
Serial.println("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
SDpresent=false;
}
else {
Serial.println("card initialized.");
SDpresent=true;
SDlog("card initialized.");
}
//Sync time and date
setSyncProvider(getNtpTime);
setSyncInterval(3601);
while(timeStatus()== timeNotSet) {
Serial.println("Synching Clock"); // wait until the time is set by the sync provider
SDlog("Synching Clock");
}
delay(1000);
}
void loop(){
while(!Serial.available()){
Serial.println("Waiting for serial");
SDlog("Waiting for serial");
}
if(getSerialString()){
String RPS3data=ReadBuffer;
RPS3data=RPS3data.trim();
WebClient(RPS3data); //Save to db
//Save to SD
if(SDpresent){
String ora=hour();
String minuti=formatDigits(minute());
String secondi=formatDigits(second());
String giorno=day();
String mese=month();
String anno=year();
String record=ora+":"+minuti+":"+secondi+" "+giorno+" "+mese+" "+anno+";"+RPS3data;
Serial.println(record);
SDwrite(record);
}
delay(500);
}
}
/*******************************************************************************
* WebClient function
*******************************************************************************/
void WebClient(String webString){
Client client(server, 82); //ip,port (usually 80)
if (client.connect()) {
Serial.println("connected");
SDlog("connected");
// Make a HTTP request:
client.println("GET /rotex.php?user=username&password=password&data=" + webString + " HTTP/1.0");
client.println();
}
else {
// if you didn't get a connection to the server:
Serial.println("connection failed");
SDlog("connection failed");
}
Serial.println("disconnecting.");
SDlog("disconnecting.");
client.stop();
}
/*******************************************************************************
* Get NTP time function
*******************************************************************************/
unsigned long getNtpTime() {
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);
if ( Udp.available() ) {
Udp.readPacket(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
//the timestamp starts at byte 40 of the received packet and is four bytes,
// or two words, long. First, esxtract the two words:
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
const unsigned long seventyYears = 2208988800UL - timeZoneOffset;
// subtract seventy years:
return secsSince1900 - seventyYears;
}
return 0; // return 0 if unable to get the time
}
/*******************************************************************************
* send an NTP request to the time server at the given address
*******************************************************************************/
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(byte *address){
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the 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 zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.sendPacket( packetBuffer,NTP_PACKET_SIZE, address, 123); //NTP requests are to port 123
}
/*******************************************************************************
* Write to SD card function
*******************************************************************************/
void SDwrite(String SDString){
// make a string for assembling the data to log:
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("rotex.csv", FILE_WRITE);
// if the file is available, write to it:
if (dataFile){
dataFile.println(SDString);
dataFile.close();
// print to the serial port too:
//Serial.println(SDString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening rotex.csv");
}
}
/*******************************************************************************
* log to SD card function
*******************************************************************************/
void SDlog(String SDString){
// make a string for assembling the data to log:
if(SDpresent){
File dataFile = SD.open("log.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile){
dataFile.println(SDString);
dataFile.close();
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening rotex.csv");
}
}
}
/*******************************************************************************
* Format minutes and seconds
*******************************************************************************/
String formatDigits(int digits){
if(digits < 10){
String dig = digits;
return "0"+dig;
}
else {
String dig = digits;
return dig;
}
}
/*******************************************************************************
* Read from serial
*******************************************************************************/
boolean getSerialString(){
byte ReadIndex = 0; //was static
while(Serial.available()>0){
char incomingbyte = Serial.read();
//Let's check our index here, and abort if we're outside our buffer size
//We use our define here so our buffer size can be easily modified
if(ReadIndex==BUFFERSIZE){
//Oops, our index is pointing to an array element outside our buffer.
ReadIndex = 0;
break;
}
if(incomingbyte==STRINGTERMINATOR){
ReadBuffer[ReadIndex] = 0; //null terminate the C string
//Our data string is complete. return true
return true;
}
else{
ReadBuffer[ReadIndex++] = incomingbyte;
ReadBuffer[ReadIndex] = 0; //null terminate the C string
}
}
//We've read in all the available Serial data, and don't have a valid string yet, so return false
return false;
}