Go Down

Topic: Client, Server and UDP on one Arduino (Read 3390 times) previous topic - next topic

Hi, i've read a few threads with no real suggestion how fix my current problem:

According to the datasheet of the Wiznet Ethernet Shield (http://arduino.cc/en/Main/ArduinoEthernetShield) it supports up to four simultanios connections.

So my idea was to build the following:

Web-Server (controling arduino - running in void loop())
Pachube Client (receives Data through XBEE)
UDP Client (NTP Sync every 12 Hours)

I was able to get the web-server running.

I've also found some pachube-clients - one works well.

To get NTP i've also figured out a few - and got it running.

Combinend to on 18k program it doesn't even get through setup()....

Code: [Select]

#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>
#include <TextFinder.h>
#include <Time.h>
#include <TimeAlarms.h>
#include <NewSoftSerial.h>

// Network
byte mac[] = {0xDE,0xAD, 0xBE,0xEF,0xFE,0xED};
byte ip[] = { 192,168,0,177 };
byte subnet[] = {255,255,255,0};
byte gateway[] = {192,168,0,1};
byte pachube[] = {173,203,98,29};
Server server(80);
//Client client(pachube, 80);

// NTP Time stuff
unsigned int localPort = 8888;
byte timeServer[] = { 192,53,103,108 };
const int NTP_PACKET_SIZE= 48;
byte packetBuffer[ NTP_PACKET_SIZE];

// NewSoftSerial
uint8_t pin_in = 2, pin_out = 3;
NewSoftSerial mySerial(pin_in, pin_out);

// XBee
const byte startbyte = 0x7E;
const byte RemoteAT = 0x17;
const byte ApplyChanges = 0x02;

// Runtime-Variables
boolean delayrun = false;

// Pachube-Stuff
float xbee_temp_01 = 0;
float xbee_light_01 = 0;

void setup()
{
  Serial.begin(9600);
  mySerial.begin(9600);
  //Serial.println("Serial Ports");
  Ethernet.begin(mac, ip, gateway, subnet);
 
  server.begin();
  Udp.begin(localPort);

  // Initial Tasks
  Alarm.timerOnce(15, getNTP);
 
  // Daily Tasks
  Alarm.alarmRepeat(18,10,0, getNTP);
  Alarm.alarmRepeat(5,10,0, getNTP);
  Alarm.alarmRepeat(23,59,40, endofday);

  // Repeating Tasks
  Alarm.timerRepeat(60, RepeatTask);
 
  // Timers for prog
  Alarm.alarmRepeat(20,0,0, prog1_an_timerless);
  Alarm.alarmRepeat(20,10,0, prog_aus);
  Alarm.alarmRepeat(20,10,2, prog2_an_timerless);
  Alarm.alarmRepeat(20,20,2, prog_aus);

  Serial.println("Setup done");
}


I've also raised the number of available Timers in TimeAlarms.h to #define dtNBR_ALARMS 20 so that i can have plenty alarms.

Anybody have an idea, how to fix this??

robtillaart


How much RAM are you using?
UNO has only 2K ... and seeing the list of includes that could be a point of attention ...


As the NTP server is needed only once per 12 hours, I would not start listening in setup() but make a function that is called once every 12 hours that creates the NTP client fetch a time and removes the client again. To fetch the time through NTP normally uses less than a second. Think you should consider to shutdown the webserver for that second so it will free sockets...
   
If you add Serial.print statements between the lines of setup() how far does setup() go before it freezes?
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

I'm using an arduino uno - Binary sketch size: 15470 bytes (of a 32256 byte maximum)

It freezes completely (no message from setup()) if add the following to void loop()
if (year() == 1970){
    Serial.println("Datum falsch!");
    getNTP();
}

In the getNTP() i'll added the Udp.begin(localPort); and removed it from the setup()

my loop() looks like this now:
Code: [Select]
void loop()
{
  Serial.println("Loop startet");
  delay(1000);
  Alarm.delay(0);
  if (year() == 1970){
    Serial.println("Datum falsch!");
    getNTP();
  }
  Client client = server.available();
  if (client) {
    Serial.println("Webserver Start");
    TextFinder  finder(client ); 
    while (client.connected()) {     
      if (client.available()) {
        boolean dodelay = false;
        boolean dostop = false;
        boolean dogo = false;       
        if( finder.find("GET /") ) {             
          while(finder.findUntil("command", "\n\r")){ 
            char type = client.read();
            int syntax_1 = finder.getValue();
            switch (type);


And ends with: client.stop();

Should i store this in an extra procedure ?

Could it also be, that i've added to much Timers?

The client.stop command stops the server also, right?

If I understand your suggestion right the "program" should run like this:

Webserver, NTP, Pachube
Ethernet Init -> UDP init -> NTP get -> UDP stop -> Webserver start -> look for webserver data -> Webserver stop -> Pachube Client start-> Pachube update -> Pachub Client Stop -> End
Own function:
NTP - including UDP init, NTP get, UDP stop
Webserver - including Webserver start, look for webserver data, Webserver stop
Pachube - including Pachube client init, Pachube update, Pachube Client stop


Webserver, Pachube
Ethernet Init -> Webserver start -> look for webserver data -> Webserver stop -> Pachube Client start-> Pachube update -> Pachube Client Stop -> End
Webserver - including Webserver start, look for webserver data, Webserver stop
Pachube - including Pachube client start, Pachube update, Pachube Client stop

Are the following commands for the above the right choice?
Ethernet init: Ethernet.begin(mac, ip, gateway, subnet);
UDP init: Udp.begin(localPort);
UDP stop: No idea
Webserver start: server.begin(); (Is the port 80 needed??) - Client client = server.available();
Webserver stop: client.stop();
Pachube client start: Client client(pachube, 80);
Pachube client stop: client.stop();

Thx for your help.

robtillaart

Quote
I'm using an arduino uno - Binary sketch size: 15470 bytes (of a 32256 byte maximum)


That is the amount of FLASH (also known as program memory) THe Arduino has separated program and data memory.




Quote
If I understand your suggestion right the "program" should run like this:

Webserver, NTP, Pachube
Ethernet Init -> UDP init -> NTP get -> UDP stop -> Webserver start -> look for webserver data -> Webserver stop -> Pachube Client start-> Pachube update -> Pachub Client Stop -> End
Own function:
NTP - including UDP init, NTP get, UDP stop
Webserver - including Webserver start, look for webserver data, Webserver stop
Pachube - including Pachube client init, Pachube update, Pachube Client stop

Yes you got the idea

in pseudocode
loop()
{
  HowLongCanTheWebRun = max (24 hours, howLongUNtil NTP, howLongUNtilPachube);

  runTheWeb for HowLongCanTheWebRun;

  if (time to runNTP) doNTP();
 
  if (time to Pachube) doPachube()
}

Do you have a link to the Alarm library used?


Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Thanks,

How can i determine, how much programm and data memory I've used?

the link to the time-library: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1263305457

so i will try to build the code with a few if's and let the timer-thing rest for a while...

How to stop the udp client? Does it "unload" automaticly, when the runtime of the function ends or do i need to put a command at the end of the function?
Quote

Ethernet init: Ethernet.begin(mac, ip, gateway, subnet);
UDP init: Udp.begin(localPort);
UDP stop: No idea
Webserver start: server.begin(); (Is the port 80 needed??) - Client client = server.available();
Webserver stop: client.stop();
Pachube client start: Client client(pachube, 80);
Pachube client stop: client.stop();


Are the other commands right?

Thanks for the pseudo-code - it helps me to better understand the flow.

PaulS

Quote
How to stop the udp client?

The UDP class derives from Stream. It has a stop() method.

Code: [Select]
/* Release any resources being used by this UDP instance */
void UDP::stop()
{
  if (_sock == MAX_SOCK_NUM)
    return;

  close(_sock);

  EthernetClass::_server_port[_sock] = 0;
  _sock = MAX_SOCK_NUM;
}

I can't find this in my udp.h or udp.cpp

Where did you get the your udp library?

my new experiment also don't work...

Code: [Select]
#include <SPI.h>
#include <Ethernet.h>
#include <Udp.h>
#include <TextFinder.h>
#include <Time.h>
#include <TimeAlarms.h>
#include <NewSoftSerial.h>

// Network
byte mac[] = {0xDE,0xAD, 0xBE,0xEF,0xFE,0xED};
byte ip[] = {192,168,0,177};
byte subnet[] = {255,255,255,0};
byte gateway[] = {192,168,0,1};
byte pachube[] = {173,203,98,29};

// NTP Time stuff
unsigned int localPort = 8888;
byte timeServer[] = { 192,53,103,108 };
const int NTP_PACKET_SIZE= 48;
byte packetBuffer[ NTP_PACKET_SIZE];

// NewSoftSerial
uint8_t pin_in = 2, pin_out = 3;
NewSoftSerial mySerial(pin_in, pin_out);

// XBee
const byte startbyte = 0x7E;
const byte RemoteAT = 0x17;
const byte ApplyChanges = 0x02;

// Runtime-Variables
boolean delayrun = false;

// Pachube-Stuff
float xbee_temp_01 = 0;
float xbee_light_01 = 0;

void setup()
{
  Serial.begin(9600);
  mySerial.begin(9600);
  Serial.println("Serial Ports");
  Ethernet.begin(mac, ip, gateway, subnet);
  Serial.println("Ethernet done");
}

void loop()
{
  Serial.println("Loop start");
  delay(1000);
  Alarm.delay(0);
  if (year() == 1970){
    Serial.println("Date not set!");
    getNTP();
  }
  // Time-dependent Stuff
  switch (hour()){
    case 23:
    switch (minute()){
      case 20:
      //getNTP();
     
      case 54:
      endofday();
    }
    break;
   
    case 20:
    switch (minute()){
      case 1:
      prog_ein(11);
      break;
     
      case 11:
      prog1_aus();
      break;
     
      case 12:
      prog_ein(21);
      break;
     
      case 22:
      prog2_aus();
      break;
    }
  }
  if (second() == 30){
    RepeatTask();
  }
   
  // Webserver
  webserver();
}

robtillaart

small remark...

Code: [Select]
  if (year() == 1970){
    Serial.println("Date not set!");
    getNTP();
  }


This part should typically be in setup, in fact in setup() you call getNTP() allways!!

furthermore the    delay(1000);  in loop() is not needed . Why wait ...
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

sorry for being a "wisenheimer" but if the year changes to 2011 he would'nt do getNTP()

The delay was an relict from some test (where i println'ed that the loop was reached - it messed up the serial monitor)

tried it with getNTP in setup - still does'nt "boot" - no response to serial - even no response to ping... (Host is down)

#9
Jul 19, 2011, 10:00 pm Last Edit: Jul 19, 2011, 10:02 pm by bjoernhoefer Reason: 1
a little success - after removing the udp.h and TimeAlarms.h

Strange thing: The Arduino "reboots" pretty often (Seeing the Serial done and Ethernet done Messages...)

Much more strange thing:
After the success of getting the sketch back to work, i've tried to enable udp.h (without the code for getNTP()) - works fine.

When I add the getNTP code it does'nt "boot"

Code: [Select]

// NTP-Stuff
void getNTP()
{
 Serial.println("NTP Begins");
 Udp.begin(localPort);
 delay(10);
 sendNTPpacket(timeServer); // send an NTP packet to a time server
 delay(1000);  
 if ( Udp.available() ) {  
   Udp.readPacket(packetBuffer,NTP_PACKET_SIZE);
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
   unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);  
   unsigned long secsSince1900 = highWord << 16 | lowWord;  
   const unsigned long seventyYears = 2208988800UL;    
   unsigned long epoch = secsSince1900 - seventyYears;  
     
   setTime(epoch);
   int dst = hour() + 2;
   setTime(dst,minute(),second(),day(),month(),year());
 }
}

unsigned long sendNTPpacket(byte *address)
{
 memset(packetBuffer, 0, NTP_PACKET_SIZE);
 packetBuffer[0] = 0b11100011;
 packetBuffer[1] = 0;
 packetBuffer[2] = 6;
 packetBuffer[3] = 0xEC;
 packetBuffer[12]  = 49;
 packetBuffer[13]  = 0x4E;
 packetBuffer[14]  = 49;
 packetBuffer[15]  = 52;  
 Udp.sendPacket( packetBuffer,NTP_PACKET_SIZE,  address, 123);
}


I've got my upd libraries from there: http://code.google.com/p/arduino/source/browse/?r=1094#svn%2Ftrunk%2Flibraries%2FEthernet%253Fstate%253Dclosed

I don't get the clue...

PaulS

Quote
When I add the getNTP code it does'nt "boot"

This is almost certainly a sign that you have run out of memory.

hmmm... sounds not too good....

is there any possibility to "save" some of this - or should I get a Arduino Mega, do I have other options?

Sorry for asking stupid questions...

Go Up