Hard Fault & Slow UDP Traffic

Race timing software on my computer is sending the time to the Argon 10 times a second. It is in this format (T00:00:00:0) Our clock is in this format (00:00:00) and utilizes a series of shift registers. If I am watching the serial console the time skips 2-4 tenths of a second regularly Is it unreasonable to think that the Argon would be able to keep up? Or do I need to make and adjustment in the code?

Additionally, I have tested the “setSeg()” function separately and I am was able to display the correct digits on the clock. I have changed something and now I am getting a hard fault. I have looked up and down the page over and over. But for the life of me, I just am not seeing the issue. I know it has something to do with the last line " g_registerArray[0] = g_digits[acs[dpos]];" If I comment it out it runs fine. Can anyone lend a hand?

SYSTEM_THREAD(ENABLED)

char acs[20];
char bcs[20];
uint16_t UDPPort = 8888;    //UDP listening port.
uint16_t UDPMaxPacketSize = 50;   //Network MTU size.
int LE = A3;
int CLK = A1;
int SDI = A2;
UDP Udp;
byte g_registerArray [11];      // Array of numbers to pass to shift registers
byte g_digits [18];             // Definitions of the 7-bit values for displaying digits
int dpos;

void setup() {
    waitUntil(Particle.connected);//Network must be connected before calling Udp.begin() per photon reference.
    
    Serial.begin(115200);   // open serial over USB

    IPAddress myIP = WiFi.localIP();
    String wIP = myIP;
    Particle.publish("IP", wIP);
    

    //Start UDP for receiving commands via wi-fi.
    Udp.begin(UDPPort);

    pinMode(SDI, OUTPUT); 
    pinMode(LE, OUTPUT);
    pinMode(CLK, OUTPUT);

    //Map digits to array
    g_digits [48] = 63;   //0
    g_digits [49] = 6;    //1
    g_digits [50] = 91;   //2
    g_digits [51] = 79;   //3
    g_digits [52] = 102;  //4
    g_digits [53] = 109;  //5
    g_digits [54] = 125;  //6
    g_digits [55] = 7;    //7
    g_digits [56] = 127;  //8
    g_digits [57] = 111;  //9
    g_digits [32] = 0;    //space

    Particle.publish("Setup Complete");
    
}

void loop() {
    bool rxError = true;
    
    int size = Udp.receivePacket((byte*)acs, UDPMaxPacketSize-1);
    if (size > 0 && size < UDPMaxPacketSize) {
        acs[size] = 0;
        //Check to see if time is new
        if(strcmp(acs, bcs) != 0){
            strcpy(bcs,acs);
            Serial.println(acs);
           //Determine what digit to start on Time includes Hours Start at 1, no hours start at 4
            if (size == 9){
                dpos = 1;
            } else {
                dpos = 4;
            }
            setSeg();
        }
        rxError = false;
    } else if (size < 0) {
        rxError = true;
        Udp.begin(UDPPort);
    } 
}


void setSeg() {
        Serial.println(dpos);
        Serial.println(acs[dpos]);
        Serial.println(g_digits[acs[dpos]]);
    

        g_registerArray[0] = g_digits[acs[dpos]];
//Remainder of shift registers left off for brevity
}

You are defining this byte g_digits [18]; but then you do this

You are corrupting data with these assignments as you are writing outside of your array.

same here

You intend to read up to 49 bytes into a 20 byte array

First you need to consider that UDP is a protocol without guaranteed delivery, so you may just not get all the packets you'd expect.
Additionally if you don't need the Particle cloud connection you could disconnect from the cloud and hence avoid the regular cloud heartbeat.

There is a known issue with periodic spikes in UDP latency on the Argon. I've seen it as high as 252 milliseconds.

I didn't test with the cloud deactivated, so that might be worth testing as ScruffR suggested.

1 Like

Well that embarrassing. That’s what I get for trying to work on this stuff in the middle of the night. The arrays are fixed and I am no longer receiving the hard fault.

I tried disconnecting from the cloud, utilizing ethernet connection and disabling SYSTEM_THREAD(ENABLED) (saw this mentioned in another thread). I have the option of sending the time once a second. I tried that and it actually is worse. It might skip 4-6 seconds at a time. I changed it back to sending every 10th of a second and I am only having skips of 0.3-0.5 seconds. The time doesn’t seem to lag behind. Really. When the time updates on the serial console it matches the timing software on the computer almost perfectly. It’s just that the time doesn’t update often enough on the console. Would there be anything in my code that could be slowing me down? Would there be any chance that TCP would be any better from a speed prospective?

On a whim I added a 20ms delay in my loop this morning and it’s made a huge difference. I’m running tenths of a second. And I’m only seeing maybe a 1/10 of a second skip about every minute or so now. That’s completely acceptable for our needs. Thanks for the help guys.

1 Like