Pages: [1]   Go Down
Author Topic: web server and udpntp client at the same time  (Read 2189 times)
0 Members and 1 Guest are viewing this topic.
Santander
Offline Offline
Newbie
*
Karma: 0
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everyone,

I have an Arduino UNO R2 with an Ethernet Shield R3 and a Xbee Shiel v1.1. I am using the Arduino IDE 0023.

Well, my question is if I can use the board as a server and as a client. I was reading other posts but I don´t find anything. I copied the example that brinds the Arduino IDE (UdpNtpClient).

So, maybe I have to initiate the board as a client only when I need it. The example asks the time and I barely use it. I´ve read in other posts it tries to share the socket.

My program receives information for remote nodes through radio communication, this information is written on a file and saved in the microSD. When I open a browser and tipe the ip of the server (the board) it prints the web (that also it´s stored in the microSD) and shows the information of the files.  Well, sometimes it works others no.

I imagine that it exists an incompability between the server and the client, could you help me?

Thank you!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 613
Posts: 49343
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I am using the Arduino IDE 0023.
Lots of improvements to the ethernet interface classes in 1.0.0, 1.0.1, and 1.0.2. Perhaps it's time to upgrade.

Asking questions in a programming forum without posting code is like going to a car dealer looking for a bus schedule.
Logged

Offline Offline
Full Member
***
Karma: 4
Posts: 187
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Lots of improvements to the ethernet interface classes in 1.0.0, 1.0.1, and 1.0.2. Perhaps it's time to upgrade.

Asking questions in a programming forum without posting code is like going to a car dealer looking for a bus schedule.

I agree with you PaulS
Logged

From Idea To Invention

Miramar Beach, Florida
Offline Offline
Faraday Member
**
Karma: 146
Posts: 6022
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is server and client code combined for IDE v0023:
http://arduino.cc/forum/index.php/topic,80137.msg606219.html#msg606219
It is web server and email client, but NTP client should work ok also.

Upgrade to a newer version. Pre-v1.0 versions had a bug in the ethernet library.
Logged

Santander
Offline Offline
Newbie
*
Karma: 0
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

sorry for not adding the code. Well before pasting the other code, I've trying with an easier than mine. I copied the original example for web server and I added the original for udpnptclient mixing both.

When I open a browser and type the ip address of the server 192.168.112.31 appears the hour only if I refresh the page.

If you run only the web server code example, you'll realize that the values of the page update itself without reloading the page. But adding the ntp service... it works badly, I checked on the monitor and sometimes reloading the browser you can see this:
Code:
hora: ™M~ž• À8÷+$Ö§Q…€³šHTTP/1.1 200 OK Content-Type: application/json Connection: close {"fioList":[{"asynchronus":"0","sleepCycle":"0"},{"address":"2","temperature":"18","humidity":"78","asynchronus":"0","sleepCycle":"0","uid":"0000"}]} †YdHTTP/1.1 200 OK Content-Type: text/html hora: 15:42:42
0 OK Content-Type: text/html hora: 15:24:54
B]S냈%kVsÏDiê)z41 ÅÒ…CWA¬Œ‹Š”C!S  !„V#“9͈þøÆ• Q…™ gÃãÍÃýBž –pƒ€ù § ³3!HTTP/1.1 200 OK vÂÓW"Òl-ÇHTTP/1.1 200 OK cP±p´vã¿‹Â"¦Y 5"¹ˆˆR$ahàz"k”Àঁ;+ZǏ‹6ÿ\g½¹›nÁ;¿ŸŸPQÕ#úƳUÈ]¢˜¦Añ§\Í÷Üñˆ»OP“U+^@Hŏª­\½A¢ÔHä"!WþåzØj—ÕM@º?³Ù-AC!ì y&± IdèPTYô 큫¡ê¸;ªÅíü/SØçž…>·?!ó¸ óp¹CmMÛHTTP/1.1 200 OK Content-Type: text/html hora: 0:56:1
B 2®¤˜åJPQLËeròXP“EØ$Â@~HTTP/1.1 200 OK Content-Type:HTTP/1.1 200 OK Content-Type: text/ht5:26:29
Z›p*Ù94èŽÇ˜=ò£DÇÐVÁ\:YÒJÕ‚Ó‘a+m< Ñ´gØáäÕO©öéàÝëÌ óÁ äÙ¾†ƒH‰y™£²ëäÂDh¢HTTP/1.1 200 OK HTTP/1.1 200 OK Content-Type: text/html ho5:42:42
a: ml hora: V)/"$—û=õÔö1Ú‚1 ”c(ŒÂÓî¥çtK{‘B2"s ½Š×B"ñ;p]ŸRÙ«‘ãZm.%vñ¤P–ù’”¤x0®Ü XÅw)9eüNƒ®Î(ÏæÇDV=Âp  ` tÚ³HTTP/1.1 200 OK Content-Type: text/html hora: 15:42:42
/> @?1„Ó;qúš-®bêäJB‚JH`• HTTP/1.1 200 OK Content-Type: text/html hora: 15:26:29
 Q Ý@¹å$ED"y øT3E€n‰PüßP[F sÌË°e„JX€žêHTTP/1.1 200 OHTTP/1.1 200 OK text/html hora: 0:0:0
y%HTTP/1.1 200 OK Content-Type: text/html hora: 15:26:29
15:26:29ÌiMA.å=¶¾Çyp h°W§¤¾ù I!†;âå+K4RÖ3ʏ ƒÑG&²â@f¡É¬žP øIÔy»Ïǃ_›2†HTTP/1.1 200 OK Content-Type: text/html hora: 15:26:29
EpXþfÐHTTP/1.1 200 OK Content-Type: text/html hora: 0:0:0
€Ù 'LAelAQAhT„µ/ŸHTTP/1.1 200 Ohora: 15:26:29
  ‰&çÆXåaB{fContHTTP/1.1 200 OK Content-Type: text/html ÕS^˜“ë4aè5‡NaàRè™Í¥,Ő<ÔS’*Ëþ ýöçD^Õ²í?ì)ÀContent-Type: text/html hora: ™M~ž• À8÷+$Ö§Q…€³šHTTP/1.1 200 OK Content-Type: application/json Connection: close {"fioList":[{"asynchronus":"0","sleepCycle":"0"},{"address":"2","temperature":"18","humidity":"78","asynchronus":"0","sleepCycle":"0","uid":"0000"}]} †YdHTTP/1.1 200 OK Content-Type: text/html hora: 15:42:42
0 OK Content-Type: text/html hora: 15:24:54
B]S냈%kVsÏDiê)z41 ÅÒ…CWA¬Œ‹Š”C!S  !„V#“9͈þøÆ• Q…™ gÃãÍÃýBž –pƒ€ù § ³3!HTTP/1.1 200 OK vÂÓW"Òl-ÇHTTP/1.1 200 OK cP±p´vã¿‹Â"¦Y 5"¹ˆˆR$ahàz"k”Àঁ;+ZǏ‹6ÿ\g½¹›nÁ;¿ŸŸPQÕ#úƳUÈ]¢˜¦Añ§\Í÷Üñˆ»OP“U+^@Hŏª­\½A¢ÔHä"!WþåzØj—ÕM@º?³Ù-AC!ì y&± IdèPTYô 큫¡ê¸;ªÅíü/SØçž…>·?!ó¸ óp¹CmMÛHTTP/1.1 200 OK Content-Type: text/html hora: 0:56:1

and in the monitor:

cliente
cliente

1:14:40
1:14:40
1:14:41
1:15:13cliente
cliente
cliente

1:15:13cliente
cliente
cliente
cliente

cliente is painted when I refresh the page, and the hour each 10 seconds ... sometimes the hours is correct...


Code:
#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,112, 31 };

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
Server server(80);

unsigned int localPort = 8888;      // local port to listen for UDP packets

byte timeServer[] = {192, 43, 244, 18}; // time.nist.gov NTP server

const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message

byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets

int hora, minuto, segundo;
unsigned long time;

void setup()
{
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.begin(9600);
  time = millis();
  hora = 0;
  minuto = 0;
  segundo = 0;
}


void loop()
{
  // listen for incoming clients

  Client client = server.available();
 
  if (client) {
    Serial.print("cliente conectado\n");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();

          // output the value of each analog input pin

            client.print("hora: ");
            client.print(hora);
            client.print(":");
            client.print(minuto);
            client.print(":");
            client.print(segundo);
            client.println("<br />");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }
  if ( (millis() - time) > 10000 ) {

    sendNTPpacket(timeServer); // send an NTP packet to a time server
    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;     
      unsigned long epoch = secsSince1900 - seventyYears; 
      // print the hour, minute and second:
 
      hora   = (epoch  % 86400L) / 3600; // print the hour (86400 equals secs per day)
      minuto = (epoch  % 3600) / 60; // print the minute (3600 equals secs per minute)
      segundo = epoch %60;
      Serial.println();
      Serial.print(hora);
      Serial.print(":");
      Serial.print(minuto);
      Serial.print(":");
      Serial.print(segundo);
      time = millis();
    }
  }
}


// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(byte *address)
{
  Udp.begin(localPort);
  // 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
Logged

0
Offline Offline
Tesla Member
***
Karma: 143
Posts: 9598
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Client-server-UDP-time test code from various sources. Open the serial monitor and send an e, and the time should be returned.

Code:
//zoomkat 12-08-11, combined client and server
//simple button GET with iframe code
//for use with IDE 1.0
//open serial monitor and send an g to test client and
//see what the arduino client/server receives
//web page buttons make pin 4 high/low
//use the \ slash to escape the " in the html
//address will look like http://192.168.1.102:84 when submited
//for use with W5100 based ethernet shields


//NTP server implementation added by RobertJP

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
IPAddress ip(192,168,1,102); // ip in lan
IPAddress gateway(192,168,1,1); // internet access via router
IPAddress subnet(255,255,255,0); //subnet mask
IPAddress myserver(208,104,2,86); // zoomkat web page
EthernetServer server(84); //server port
EthernetClient client;
String readString;

//////////////////////NTP declarations
IPAddress timeServer(77,245,91,218); // time.nist.gov NTP server
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
EthernetUDP Udp; // A UDP instance to let us send and receive packets over UDP
unsigned int localPort = 8888; //Port to listen for UDP packets

void setup(){
  pinMode(5, OUTPUT); //pin selected to control
  Ethernet.begin(mac,ip,gateway,gateway,subnet);
  server.begin();
  Serial.begin(9600);
  Serial.println("server/client 1.0 test 12/08/11"); // keep track of what is loaded
  Serial.println("Send an g in serial monitor to test client"); // what to do to test client
  Udp.begin(localPort);
  Serial.println("UDP started");
}

void loop(){
  // check for serial input
  if (Serial.available() > 0)
  {
    byte inChar;
    inChar = Serial.read();
    if(inChar == 'g')
    {
      sendGET(); // call sendGET function
    }
  } 

  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        //read char by char HTTP request
        if (readString.length() < 100) {

          //store characters to string
          readString += c;
          //Serial.print(c);
        }

        //if HTTP request has ended
        if (c == '\n') {

          ///////////////
          Serial.println(readString); //print to serial monitor for debuging

            //now output HTML data header
          if(readString.indexOf('?') >=0) { //don't send new page
            client.println("HTTP/1.1 204 Robert");
            client.println();
            client.println(); 
          }
          else {
            client.println("HTTP/1.1 200 OK"); //send new page
            client.println("Content-Type: text/html");
            client.println();

            client.println("<HTML>");
            client.println("<HEAD>");
            client.println("<TITLE>Arduino GET test page</TITLE>");
            client.println("</HEAD>");
            client.println("<BODY>");

            client.println("<H1>Zoomkat's simple Arduino 1.0 button</H1>");

            client.println("<a href=\"/?on\" target=\"inlineframe\">ON</a>");
            client.println("<a href=\"/?off\" target=\"inlineframe\">OFF</a>");

            //client.println("<IFRAME name=inlineframe src=\"res://D:/WINDOWS/dnserror.htm\" width=1 height=1\">");
            client.println("<IFRAME name=inlineframe style=\"display:none\" >");         
            client.println("</IFRAME>");

            client.println("</BODY>");
            client.println("</HTML>");
          }

          delay(1);
          //stopping client
          client.stop();

          ///////////////////// control arduino pin
          if(readString.indexOf("on") >0)//checks for on
          {
            digitalWrite(5, HIGH);    // set pin 4 high
            Serial.println("Led On");
          }
          if(readString.indexOf("off") >0)//checks for off
          {
            digitalWrite(5, LOW);    // set pin 4 low
            Serial.println("Led Off");
          }
          //clearing string for next read
          readString="";

        }
      }
    }
  }
}

void sendGET()
{
  Serial.println("Send GET");
  sendNTPpacket(timeServer); // send an NTP packet to a time server
   // wait to see if a reply is available
  delay(1000); 
  if ( Udp.parsePacket() ) {
    Serial.println("Got it!");
    // We've received a packet, read the data from it
    Udp.read(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; 
    Serial.print("Seconds since Jan 1 1900 = " );
    Serial.println(secsSince1900);               

    // now convert NTP time into everyday time:
    Serial.print("Unix time = ");
    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;     
    // subtract seventy years:
    unsigned long epoch = secsSince1900 - seventyYears; 
    // print Unix time:
    Serial.println(epoch);                               


    // print the hour, minute and second:
    Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
    Serial.print(1+(epoch  % 86400L) / 3600); // print the hour (86400 equals secs per day)
    Serial.print(':'); 
    if ( ((epoch % 3600) / 60) < 10 ) {
      // In the first 10 minutes of each hour, we'll want a leading '0'
      Serial.print('0');
    }
    Serial.print((epoch  % 3600) / 60); // print the minute (3600 equals secs per minute)
    Serial.print(':');
    if ( (epoch % 60) < 10 ) {
      // In the first 10 seconds of each minute, we'll want a leading '0'
      Serial.print('0');
    }
    Serial.println(epoch %60); // print the second
  }
  Serial.println("Done!");
}

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& 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.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer,NTP_PACKET_SIZE);
  Udp.endPacket();
}

Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 613
Posts: 49343
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But adding the ntp service... it works badly
And you STILL haven't posted any code. You need to find a bus terminal.
Logged

Santander
Offline Offline
Newbie
*
Karma: 0
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

this is the code. If I comment all related to udp it works normally but when not the board don´t respond to any request from the internet.

Code:
/* 6 Noviembre
 Errores:
  * #include <string.h>
    myFile.print() no acepta un string crea archivos ilegibles
    error, al crear un fichero FX.JS mete información de Y
  * Alimentar XBee Shield con alimentacion aparte, se pueden generar picos de consumo
    que resetea la placa
  * Debug
    #include <NewSoftSerial.h> o #include <SoftwareSerial.h>
    NewSoftSerial mySerial( rxPin, txPin); o SoftwareSerial mySerial( rxPin, txPin)
 Consideraciones:
  * Direcciones: considera 1byte (1 al FE) hasta 254 modulos ( @miento: 2 bytes, 0xFFFF @broadcast)
 Utilidades:
  * #include <MemoryFree.h>
    incluidas en el loop
    Serial.print("freeMemory()=");        
    Serial.println(freeMemory());
  * #include <utility/w5100.h>     // Advance Ethernet functions
    incluidas en el setup  
    W5100.setRetransmissionTime(0x07D0);  //setRetransmissionTime sets the Wiznet's timeout period, where each unit is 100us, so 0x07D0 (decimal 2000) means 200ms.
    W5100.setRetransmissionCount(3);      //setRetransmissionCount sets the Wiznet's retry count.
  */

// Librerias:
#include <XBee.h>
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>  // ocupa 5KB  
#include <Udp.h>

// Variables Globales
#define PACKET_TYPE       0  // data[0]
#define PACKET_LENGTH     1  // data[1]
#define DATA_TYPE         2  // data[2]
#define REQUEST           1
#define RESPONSE          2
#define INFO              3
#define INIT              4
#define CONFIGURATION     0
#define TEMPERATURE_FIELD 3
#define HUMIDITY_FIELD    5
#define SLEEPCYCLE_FIELD  7
#define ASYNCHRONUS_FIELD 9
#define UID_FIELD        11
#define fioMax           30
#define bufferMax       128
#define ssPin            10
#define chipSelect        4

// XBee
XBee xbee = XBee();
XBeeResponse response = XBeeResponse();  // paquete tipo respuesta
Rx16Response rx16 = Rx16Response();      // direccion de 16 bits, se puede usar la de 64
TxStatusResponse txStatus = TxStatusResponse();

// Ethernet Shield uses pins 10,11,12,13
byte mac[]     = { 0x90, 0xA2, 0xDA, 0x0D, 0x09, 0xF1 };
byte ip[]      = { 192, 168, 112, 31 };  //casa { 192, 168, 1, 4}; laboratorio{ 192, 168, 112, 31 }; CeFoNT { 193, 144, 196, 6 };
byte gateway[] = { 192, 168, 112, 1  };
byte subnet[]  = { 255, 255, 255, 0  };

Server server(80); // Puerto 80, HTTP

// SD
File myFile;

// VARIABLES GLOBALES
uint8_t fioList[fioMax] = {};            // {@1,@2,@3,...,@fioMax} Lista que contiene las direcciones de los remotos.
uint8_t fioNumber = 0;                   // numero de nodos remotos, inicialmente cero.
uint8_t uid[] = {0,0,0,0,0};               // contenedor de UID de la tarjetas
uint8_t initFrame[] = {REQUEST,1,INIT};  // Trama INIT

int bufferSize;
char buffer[bufferMax], bufferData[bufferMax];  // Buffer donde se guardan las tramas HTTP y el contenido de el POST.

unsigned long time1, time2;
int sleepCycleCoord = 0, asynchronusCoord = 0;
boolean flag1 = true, flag2 = false;

//////////////////////////// NTP SERVICE ////////////////////////////
unsigned int localPort    = 8888;      // local port to listen for UDP packets
byte timeServer[]         = { 192, 43, 244, 18 }; // time.nist.gov NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
//////////////////////////// NTP SERVICE ////////////////////////////

void setup() {
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  xbee.begin(9600);
  pinMode(8,OUTPUT);pinMode(7,OUTPUT);pinMode(6,OUTPUT);  
  pinMode(6, LOW);
  pinMode(7, HIGH);
  // Inicializacion de tarjeta
  pinMode(ssPin,OUTPUT);
  if (!SD.begin(chipSelect)) {
    //mySerial.println("initialization failed!");
    return;
  }
  //mySerial.print("\nCOORDINADOR\n");
  // funcion que borra los ficheros antiguos Fxx.JS y de cambio de ciclo.
  // BROADCAST INICIAL (puede repetirse para conocer el estado de la red)  
  sendRequest(initFrame, 3, millis()*0xFF);
  pinMode(7, LOW);
}

void loop() {
  readRequest(); // lee paquetes de entrada continuamente
  listenForClient();
  time2 = millis();
  if (flag2 == true) { // si hay pendiente por hacer...
    if (time1-time2 >= sleepCycleCoord)
      sendPendingRequest();  
      time1 = millis(); // una vez alcanzado el tiempo de sueño se tiene que renovar
  }
}

void readRequest() {
  uint8_t fioAddress; // variables locales  
  if (xbee.readPacket(10)){
    if (xbee.getResponse().isAvailable()) {
      if (xbee.getResponse().getApiId() == RX_16_RESPONSE) { // se trata de un paquete RX      
        xbee.getResponse().getRx16Response(rx16);            // almacena el paquete recibido en el objeto rx16
        switch (rx16.getData(PACKET_TYPE)) {                                
          case INFO:      // TRAMA INFO
            digitalWrite(8, HIGH);      
            fioAddress = rx16.getRemoteAddress16();
            for ( int k = 0; k < 5; k++ ) {
              uid[k] = rx16.getData(UID_FIELD + k);}
            generateJson( fioAddress, rx16.getData(TEMPERATURE_FIELD), rx16.getData(HUMIDITY_FIELD), rx16.getData(SLEEPCYCLE_FIELD), rx16.getData(ASYNCHRONUS_FIELD), uid);  // Renueva los datos de la fio en concreto
            checkNewAddress(fioAddress);
            digitalWrite(8, LOW);
          break;                                          
        }  // switch
      }  // getApiId
    }  // available
  }  // readPacket
}  // readRequest

void checkNewAddress ( uint8_t address) { // fioNumber, fioList variables globales
  for (int i = 0; i <= fioNumber; i++) {
    if (fioNumber == 0) { // TODAVIA NO HAY ELEMENTOS UNIDOS AL COORDINADOR
      fioList[i] = address;
      fioNumber = 1;
      i = fioNumber +1;
    }
    else{  // La lista no está vacía, chequea elemento a elemento
      if ( fioList[i] == address) {
        i = fioNumber +1;
      }
      else {  
        if (i == fioNumber) {  // Luego de chequear toda la lista, si no coincide es un elemento nuevo
          fioList[i] = address;
          fioNumber++;
          i = fioNumber +1;
        }
      }  // end else2
    }  // end else1
  }  // end for    
} // end checkNewAddress


boolean sendRequest(uint8_t data[], uint8_t length, uint8_t frameId) {
  uint8_t ack, option = 0, i = 3;  
  Tx16Request tx = Tx16Request(0xFFFF, option, data, length, frameId);
  do {
    xbee.send(tx);
    // Tx16Request (uint16_t addr16, uint8_t option, uint8_t *payload, uint8_t payloadLength, uint8_t frameId) (OBLIGATORIO PONERLOS TODOS!!)
    // Tx16Request (uint16_t addr16, uint8_t *payload, uint8_t payloadLength) Creates a Unicast Tx16Request with the ACK option and DEFAULT_FRAME_ID.
    if (xbee.readPacket(1000)) {  // got a response!
      if (xbee.getResponse().getApiId() == TX_STATUS_RESPONSE) {  // should be a znet tx status
        xbee.getResponse().getZBTxStatusResponse(txStatus);
        ack = txStatus.getStatus();  // get the delivery status, the fifth byte
      }  // STATUS:  0 = success, 1 = when all retries are expered and no ACK is received
    }  
    i += 1;
  }while( (i < 3) && (ack != SUCCESS) );
  
  if (ack == SUCCESS)
    return true;//mySerial.println("\nack");
  else
    return false;
}

Logged

Santander
Offline Offline
Newbie
*
Karma: 0
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void listenForClient() {
  Client cliente = server.available(); // espera a que haya datos disponilbles
  boolean currentLineIsBlank = true, flag = true;
  bufferSize = 0;
  if (cliente) {
    while (cliente.connected()) {
      while (cliente.available()) {      
        char c = cliente.read(); //mySerial.write(c);
        if (c == '\n' && currentLineIsBlank) {
          // Here is where the POST data is.  
          while(cliente.available()) {  // Datos si es un POST
            c = cliente.read();
            bufferData[bufferSize++] = c;
          }
          bufferData[bufferSize] = 0;
          cliente.println("HTTP/1.1 200 OK");
          cliente.println();  
          createRequest(bufferData);
          cliente.flush();
          cliente.stop();
        }
        else if (c == '\n') { // NEW LINE
          currentLineIsBlank = true;
          if (flag) {
            flag = false;
            buffer[bufferSize] = 0;  // no me pinta salto de linea si bufferSize+1
            bufferSize = 0;  //Serial.print(buffer);
            if ( strstr(buffer, "GET / HTTP/1.1") ) {
              filePrint("SRV.txt", cliente);
              cliente.flush();
              cliente.stop();
            }
            else
              if ( strstr(buffer, "GET /fioList HTTP/1.1") ){
                sendGetResponse(cliente);      
                cliente.flush();
                cliente.stop();
              }
              else
                if ( !strstr(buffer, "POST /changes HTTP/1.1") ) {
                  cliente.flush();
                  cliente.stop();
                }
          }
        }
        else if (c != '\r') { // you've gotten a character on the current line
          currentLineIsBlank = false;
          if ( bufferSize < bufferMax && flag )
            buffer[bufferSize++] = c;
        }
      } // client.available
    } // client.connected
  }  // end if
} // end listenForClient

void sendGetResponse(Client cliente) {
  char filename[9];
  cliente.println("HTTP/1.1 200 OK\nContent-Type: application/json\nConnection: close");
  cliente.println();
  cliente.print("{\"fioList\":[{\"asynchronus\":\"");
  cliente.print(asynchronusCoord);
  cliente.print("\",\"sleepCycle\":\"");
  cliente.print(sleepCycleCoord);
  cliente.print("\"},");
  for (int k = 0; k < fioNumber; k++) {
    sprintf (filename, "F%d.JS", fioList[k]); // si Fx.js guardado en la microSd como Fx.JS
    filePrint(filename, cliente);
    
    ////////////////////////////////////////
    filename[0] = 0;
    sprintf (filename, "G%d.JS", fioList[k]);
    if (SD.exists(filename)){
      cliente.print(",");
      filePrint(filename, cliente);
      filename[0] = 0;
      sprintf (filename, "H%d.JS", fioList[k]);
      if (SD.exists(filename)){
        cliente.print(",");
        filePrint(filename, cliente);
      }
      else {
        cliente.print("}");
      }
    }
    else {
      cliente.print("}");
    }
    ///////////////////////////////////////

    if ( (k+1) != fioNumber)
      cliente.println(",");
  }
  cliente.println("]}");
}
void filePrint (char filename[9], Client cliente){
  if (myFile = SD.open(filename, FILE_READ)) {  
    while ( myFile.available() ) {
      cliente.print( (char) myFile.read() );
    }
    myFile.close();                 // CERRAR FICHERO
  }
}

void generateJson (uint8_t address, uint8_t temperature, uint8_t humidity, uint8_t sleepCycle, uint8_t asynchronus, uint8_t uid[]) {
  char filename[9], string[9];
  int hora, minuto;
  sprintf (filename, "F%d.JS", address);// String jsonString; Usando string no lo escribe correctamente
  if ( SD.exists(filename) ) {
    SD.remove(filename);
  }
  // CREACION FICHERO
  if ((myFile = SD.open(filename, FILE_WRITE))) {  // si esta abierto ...
   myFile.print("{\"address\":\"");
   myFile.print(address, DEC);
   myFile.print("\",\"temperature\":\"");
   myFile.print(temperature, DEC);
   myFile.print("\",\"humidity\":\"");
   myFile.print(humidity, DEC);
   myFile.print("\",\"asynchronus\":\"");
   myFile.print(asynchronus, DEC);
   myFile.print("\",\"sleepCycle\":\"");
   myFile.print(sleepCycle, DEC);
   myFile.print("\",\"uid\":\"");
   for ( int k = 0; k < 4; k++ ) {
     myFile.print(uid[k], HEX);
   }
   myFile.print("\"");
   myFile.close();// CERRAR FICHERO  
  }    
  
  if ( uid[4] != 0) {
    filename[0] = 0;
    string[0] = 0;
    if ( uid[4] == 1 ){
      sprintf (filename, "G%d.JS", address);
      sprintf (string, "%c", "\"init\":\"");
    }
    else{
      if ( uid[4] == 2 ) {
        sprintf (filename, "H%d.JS", address);
        sprintf (string, "%c", "\"wait\":\"");
      }
    }
    // CREACION FICHERO
    if ((myFile = SD.open(filename, FILE_WRITE))) {  // si esta abierto ...
      myFile.print(string);
      dateTime(hora, minuto);
      myFile.print(hora,DEC);
      myFile.print(":");
      myFile.print(minuto,DEC);
      myFile.print("\"");
      myFile.close();// CERRAR FICHERO  
    }    
  }
  
}

void createRequest(char buffer[]) {
  uint8_t frameId = millis()*0x00FF;
  char *param, *equal, sleepCycle[3], asynchronus[2];
  sleepCycle[0] = 0;
  asynchronus[0] = 0;
  //sleepCycle=20&asynchronus=0  
  equal = strstr(buffer, "=") + 1;
  param = strstr(equal, "&");
  strncat(sleepCycle, equal, param-equal); // sleepCycle
  equal = strstr(param, "=") + 1;
  strncat(asynchronus, equal, 1);  // asynchronus

  uint8_t data[] = {CONFIGURATION, 2, atoi(sleepCycle), atoi(asynchronus)};  // Configuration request: [0,2,SLEEP_CYCLE,ASYNCHRONUS]
  uint8_t length = sizeof(data);
  
  if ( sendRequest( data, length, frameId) == false ) {
    saveRequest(data, length, frameId);
    flag2 = true; // al no ser enviada se levanta la bandera de pendientes
  }
  else {  // se consiguió enviar
    sleepCycleCoord  = atoi(sleepCycle);
    asynchronusCoord = atoi(asynchronus);
    if (flag1 == true){ // solo vale true la primera vez que se envía el cambio de ciclo.
      flag1 == false;
      time1 = millis(); // time 1 toma su primer valor
    }
  }
}
Logged

Santander
Offline Offline
Newbie
*
Karma: 0
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void saveRequest(uint8_t data[], uint8_t length, uint8_t frameId) {
  char filename[9];
  int k = 0;
  sprintf (filename, "%d.txt", 1);
  SD.remove(filename);  // borrar la anterior
  // CREACION FICHERO
  if ((myFile = SD.open(filename, FILE_WRITE))) {  // si esta abierto ...
    myFile.print(frameId, HEX);
    while (k < length) { 
      myFile.println(data[k], HEX);
      k++;
    }
    myFile.close();  // CERRAR FICHERO
  }     
}

void sendPendingRequest() { 
  uint8_t frameId, address, k = 0, data[] = {};
  char filename[9];
  sprintf (filename, "%d.txt", "1");
  if ( SD.exists(filename) ) {
    if ((myFile = SD.open(filename))) {  // ABRIR FICHERO
      frameId = myFile.read();
      while ( myFile.available() ){
        data[k] = myFile.read();
        k++;
      }
      myFile.close();  // CERRAR FICHERO
      if ( sendRequest(data, sizeof(data), frameId ) == true ){
        flag2 = false;  // baja la bandera de pendientes
        SD.remove(filename);
      }
    }  // myFile 
  } // SD.exists(filename)
}

// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(byte *address)
{
  Udp.begin(localPort);
  // 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
}

void dateTime(int hora, int minuto)
{
  sendNTPpacket(timeServer); // send an NTP packet to a time server

    // wait to see if a reply is available
  delay(100); 
  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;     
    unsigned long epoch = secsSince1900 - seventyYears; 
    // print the hour, minute and second:
    // UTC is the time at Greenwich Meridian (GMT)
    hora   = ((epoch  % 86400L) / 3600) + 1; // print the hour (86400 equals secs per day)
    minuto = (epoch  % 3600) / 60; // print the minute (3600 equals secs per minute)
  }
}
One of the reason I don´t use the newer version is that with version 0023 the size of libraries are smaller than in version 1.0.1 and next ones... I imagine I can reduce the library erasing functions that I don´t use but I´m not quite sure. Maybe you could tell how reduce the size of the sketch....
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 613
Posts: 49343
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

One of the reason I don´t use the newer version is that with version 0023 the size of libraries are smaller than in version 1.0.1 and next ones.
Which libraries are larger?

Quote
I imagine I can reduce the library erasing functions that I don´t use but I´m not quite sure.
The linker takes care of that, only actually linking in stuff you use. You don't have to "erase stuff you don'e use".

Quote
Maybe you could tell how reduce the size of the sketch....
Code:
char buffer[bufferMax], bufferData[bufferMax];  // Buffer donde se guardan las tramas HTTP y el contenido de el POST.
Why are you you defining two such large arrays? Each one is taking up 1/16th of the memory you have to use, unless you have a Mega.

Logged

Pages: [1]   Go Up
Jump to: