Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By caswal
#31194 Does it specifically have to be a reply to the received remote port (UDP.remotePort())? Also how necessary is the yield() call? As I changed mine to send a packet to different port (the original "G") packet. Sending "\r\n" has seemed to of helped and is stable for longer.

I also have a feeling my setup with dupont wires is just a tad sensitive. So I need to knock up something a bit more robust.
User avatar
By caswal
#31213 So built a little breakout board to the ESP-01 so I could dump the dupont wires and make a much tidier breadboard setup. Also changed over to a switching DC-DC converter. I am taking the power from my Keyboard's USB Hub. Then probing with the multimeter to set the correct voltage of the converter I noticed that my USB voltage was dropping below 3V! Hmmph. So changed it over to 5v from the 100W 5V PSU I have for my ws2812 strip lights. So I removed any of that worry.

As I type this, it still locked up. Hmmph.
User avatar
By mrburnette
#31234
caswal wrote:Does it specifically have to be a reply to the received remote port (UDP.remotePort())? Also how necessary is the yield() call? As I changed mine to send a packet to different port (the original "G") packet. Sending "\r\n" has seemed to of helped and is stable for longer.

I also have a feeling my setup with dupont wires is just a tad sensitive. So I need to knock up something a bit more robust.


From my experience, the yield() is necessary ... I try and anticipate functions that work on strings or character I/O and then use yield(). If nothing is pending in the RTOS, the yield will return fairly quickly.

IMO, breadboards are problematic. But I use a product called DeoxIT to clean the pin-plugs. I have found the Chinese "clamped" little wires problematic at any current over maybe 1 mA ... when the current get up to 80mA, I have measured more than 1/2 Volt drop!!! Replacing with Dupont wires generally works well.

So changed it over to 5v from the 100W 5V PSU I have for my ws2812 strip lights. So I removed any of that worry.


The major stability issue I have found is the DC Voltage internal impedance .... the Z needs to be as low as possible to prevent voltage drop when the the ESP8266 keys the Xmit circuitry. Also, high current power units may have more internal resistance and noise: ever see all of those titanium caps on a PC's systemboard? I'm using a Chinese made "buck" DC-DC module. The input is 5V and the output is adjustable ... I adjust for 3.3V at the ESP8266 to account for about 0.1V of drop on the breadboard. I have a 1000uF 10V cap on the breadboard across the 3.3V rail. These DC-DC modules are under $1 and I just use then with anything that is fed by an external power unit / wall brick. For battery powered, I have gone strictly to LiFePO4 cells ... they have a 3.2V output and can be easily charged to 80% of their capacity by just floating across 3.3V... therefore, the DC-DC external module set for 3.4V can take the battery to over 80% capacity ... unplug and roam for a while... come back and re-plug. For extended use, the DC-DC module can be incorporated directly into the design as a permanent fixture and then 4 alkaline batteries utilized ... the buck units are about 92% efficient.

The software that had the CR/LF removed and just the "" sent, has been running for 26 hours. It is on a breadboard.
User avatar
By mrburnette
#31266 Tardis Time UDP
Pixs:
https://www.flickr.com/photos/rayburnette/21955496558/in/dateposted-public/
https://www.flickr.com/photos/rayburnette/22143328395/in/dateposted-public/
https://www.flickr.com/photos/rayburnette/21955479658/in/dateposted-public/
https://www.flickr.com/photos/rayburnette/22130747462/in/dateposted-public/

Full code on my blog: https://www.hackster.io/rayburne/tardis-time-esp8266-ap-webserver-gps

So far, very stable UDP broadcast and receive.
Ray

Main Sketch:
Code: Select all/*
   UDP listiner for Tardis Time Server by: M. Ray Burnette 20151008
   Time Portal sends a UDP broadcast to all listeners on a random port (usually 4097)

   Compiled under Arduino 1.6.6 Hourly build 2015/09/04 04:42
    Sketch uses 342,322 bytes (78%) of program storage space. Maximum is 434,160 bytes.
    Global variables use 51,722 bytes (63%) of dynamic memory, leaving 30,198 bytes for local variables. Maximum is 81,920 bytes.

    NOTE: After power-up with a "TardisTime" GPS over UDP transmitter functioning, allow 3 - 10 minutes to initialize
          and Serial output is started.
*/

#define DEMO true
#define DIAG false

#include <Streaming.h>                                          // \Documents\Arduino\libraries\Streaming (legacy) user-installed
#include <ESP8266WiFi.h>
#include <WiFiUDP.h>
#include <Wire.h>

uint8_t      hours, minutes, seconds;                           // hours, minure, seconds,
uint8_t      day, month, year;                                  // year, month, day;
unsigned int localPort = 8888;                                  // any unused port on LAN
char         packetBuffer[UDP_TX_PACKET_MAX_SIZE];              // buffer to hold incoming packet,
char         ReplyBuffer[] = "";                                // a null
IPAddress    apIP(10, 10, 10, 1);                               // Private network address: local & gateway
IPAddress    broadcastIP(255, 255, 255, 255);                   // https://en.wikipedia.org/wiki/Multicast

String Snumbers[] = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11",
                    "12", "13", "14", "14", "16", "17", "18", "19", "20", "21", "22", "23",
                    "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35",
                    "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47",
                    "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59"};

String Smonths[] = {"???", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};

WiFiUDP           UDP;                                          // UDP protocol on STA interface, localPort


void setup()
{

  Serial.begin(9600);                                           // Initialise Serial for older PMB-648
  if(DIAG) {
   Serial << (F("2015 Ray Burnette")) << endl;
   Serial << (F("Tardis Time Listener Version 0.20151008")) << endl;
   Serial << (F("Visit my project web page on http://www.hackster.io/rayburne")) << endl << endl;
  }

  WiFi.mode(WIFI_STA);                                          // station mode
  WiFi.disconnect();
  WiFi.begin("TardisTime", "");                                 // The GPS server

  // Wire.pins(int sda, int scl), etc
  Wire.pins(0, 2);                                              // on ESP-01.
  Wire.begin();
  StartUp_OLED();                                               // Init Oled and fire up!
  Serial.println("OLED Init...");
  clear_display();                                              // done here to simplify also setXY(0,0);
  Draw_WAVES();                                                 // Graphic is optional
  sendStrXY(">>> Start-up <<<", 7, 0);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
 
  while (! UDP.begin(localPort) )                               // UDP protocol connected to localPort variable
  {
    delay(250);
  }

  clear_display();
  sendStrXY(">WiFi Connected<", 0, 0);
  char wifiIP = WiFi.localIP();
  char *P = &wifiIP;
  sendStrXY(P, 1, 0);
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  sendStrXY(">Listening: UDP<", 3, 0);

  delay(10);
  clear_display();
}


void loop()
{
  yield();                                                      // yield for RTOS
  Listener();                                                   // UPD (can you hear me now?)
}


void Listener() {
  int packetSize = UDP.parsePacket();                           // if there’s data available, read a packet
  char cTD[8];
  String Sdisplay;
  Sdisplay.reserve(8);

  if (packetSize)
  {
    IPAddress remote = UDP.remoteIP();                          // Server provided UDP listening port

    if (DIAG) {                                                 // For diags only
      Serial << endl;
      Serial << (F("Received packet of size: "));
      Serial << (packetSize);
      Serial << (F(" From remote: "));
   
      for (int k = 0; k < 4; k++)
      {
        Serial << (remote[k], DEC);
        if (k < 3)
        {
          Serial << (F("."));
        }
      }
   
      Serial << (F(", port: "));
      Serial << " UDPremotePort: " << (UDP.remotePort()) << endl;
    }                                                           // end of DIAG section

    UDP.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);             // read the packet into packetBufffer
    UDP.beginPacket(apIP, UDP.remotePort());                    // send a reply, to the IP address and port that sent us the packet we received
    UDP.write(ReplyBuffer);                                     // should not be necessary but it seems that the ESP8266
    UDP.endPacket();                                            // is stablized by the inclusion of the send
    char *p = packetBuffer;                                     // grab a pointer to buffer

    p = strchr(p, ',') + 1;                                     // position after 1st comma
    yield();
    uint32_t  time  = atoi(p);

    hours    = time / 10000;
    minutes  = (time % 10000) / 100;
    seconds = (time % 100);

    Serial << (F("Time: ")) << ((hours<10)?"0":"") << hours << ":";
    Serial << ((minutes<10)?"0":"") << minutes << ":";
    Serial << ((seconds<10)?"0":"") << seconds << endl;

    Sdisplay += Snumbers[hours] + ":" + Snumbers[minutes] + ":" + Snumbers[seconds];
    Sdisplay.toCharArray(cTD, 9);
    sendStrXY(" Tardis - Time", 0, 0);
    sendStrXY("UTC Time/Date:", 2, 0);
    sendStrXY(cTD, 4, 0);

    yield();

    // Parse to integer date field like Ladyada
    p = strchr(p, ',') + 1; // A/V?
    p = strchr(p, ',') + 1; // lat
    p = strchr(p, ',') + 1; // N/S?
    p = strchr(p, ',') + 1; // lon
    p = strchr(p, ',') + 1; // E/W?
    p = strchr(p, ',') + 1; // speed
    p = strchr(p, ',') + 1; // angle
    p = strchr(p, ',') + 1; // move pass for date DDMMYY

    yield();
   
    // nmea date field looks like: 090914 (European)
    uint32_t fulldate = atoi(p);
    day               = (fulldate / 10000);
    month             = (fulldate % 10000) / 100;
    year              = (fulldate % 100);
    Serial << "Date: " << ((month<10)?"0":"") << month << "/";
    Serial << ((day<10)?"0":"") << day << "/" << "20";
    Serial << ((year<10)?"0":"") << year << endl;
    Sdisplay = "";
    Sdisplay += Smonths[month] + Snumbers[day];
    Sdisplay.toCharArray(cTD, 6);
    sendStrXY(cTD, 4, 9);

    yield();
  }                                                             // if(packetSize)
}                                                               // Listener()