0
Offline
Newbie
Karma: 0
Posts: 19
Arduino rocks
|
 |
« on: February 03, 2012, 07:26:27 am » |
Hello, I'm getting mad trying to solve a random hang with arduino mega and ethernet shield... I tried with latest ethernet library, stop interrupts before any ethernet lib call. Even tried with a watchdog, but when the arduino hangs the watch dog doesn't reboot. Sometimes is also imposible to upload anything and I need to remove power. The incoming message rate is 10ms, and the loop never takes longer, it usually takes 7/8 ms The code is more or less like this.... Any cue? Thanks! #include <SPI.h> #include <Ethernet.h> #include <EthernetUdp.h> #include <util.h> #include <avr/wdt.h> // //Other declaration stuff // void setup() { //--- Create an interrupt to update a multiplexed display // TIMSK2 &= ~(1<<TOIE2); TCCR2A &= ~((1<<WGM21) | (1<<WGM20)); TCCR2B &= ~(1<<WGM22); ASSR &= ~(1<<AS2); TIMSK2 &= ~(1<<OCIE2A); TCCR2B |= (1<<CS22) | (1<<CS20); TCCR2B &= ~(1<<CS21); TCNT2 = 0; //tcnt2; TIMSK2 |= (1<<TOIE2); //--- Ethernet.begin(mac,ip); Udp.begin(localPort); pinMode(4,OUTPUT); digitalWrite(4,HIGH); } //-------------------------------------------------- ISR(TIMER2_OVF_vect) { iCount++; if (iCount == 5) { LCD.update(); iCount = 0; } } //-------------------------------------------------- char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //----------------------------------------- void loop() { _dataIn in; _dataOut out; cli(); int packetSize = Udp.parsePacket(); //The packet sended is 1 byte long, but packetSize is usually 10,11 or 12 ??? if (packetSize) { Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE); if (Udp.remotePort() == remotePort) { //Sometimes the remotePort is different... I not sure why. memcpy((byte *)&in, packetBuffer, sizeof(_dataIn)); //Assign incoming value to local variable //Prepare the output struct Udp.beginPacket(remoteIp, remotePort); Udp.write((byte *)&out, sizeof(_dataOut)); Udp.endPacket(); } } sei(); // //Do thing with the incoming values // }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 98
|
 |
« Reply #1 on: February 03, 2012, 08:04:38 pm » |
Just looking at it , The code will not even compile take a look at the memcpy line. Why should people waste their time, if you cannot take the time to supply a valid test case?
HC
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Tesla Member
Karma: 50
Posts: 6540
Arduino rocks
|
 |
« Reply #2 on: February 04, 2012, 02:08:41 pm » |
The code is more or less like this.... More or less most people will ignore those that won't post the actual code that is causing a problem.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 19
Arduino rocks
|
 |
« Reply #3 on: February 09, 2012, 06:39:23 am » |
Well, I was trying to make things as simple as possible, that's why I removed all not ethernet related stuff. Anyways... digging into the problem I realizes that it gets stuck in a loop inside sendUDP. I need to investigate in depth what's happening, but I supposed it can't send the package and never gets timeout. int sendUDP(SOCKET s) { W5100.execCmdSn(s, Sock_SEND); /* +2008.01 bj */ while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) { if (W5100.readSnIR(s) & SnIR::TIMEOUT) { /* +2008.01 [bj]: clear interrupt */ W5100.writeSnIR(s, (SnIR::SEND_OK|SnIR::TIMEOUT)); return 0; } }
/* +2008.01 bj */ W5100.writeSnIR(s, SnIR::SEND_OK); /* Sent ok */ return 1; }
|
|
|
|
|
Logged
|
|
|
|
|
Miramar Beach, Florida
Offline
Faraday Member
Karma: 50
Posts: 3448
|
 |
« Reply #4 on: February 09, 2012, 06:55:14 am » |
Have you tried applying this fix? http://code.google.com/p/arduino/issues/detail?id=605It affects any 16 bit register read from the w5100. It has been around long enough to pick up the nickname "the 605 bug".
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 19
Arduino rocks
|
 |
« Reply #5 on: February 09, 2012, 07:04:04 am » |
Yep, actually I'm using the latest git version of ethernet library that already have the patch.
|
|
|
|
|
Logged
|
|
|
|
|
Miramar Beach, Florida
Offline
Faraday Member
Karma: 50
Posts: 3448
|
 |
« Reply #6 on: February 09, 2012, 07:28:52 am » |
OK. That takes that out of the picture. Next, this: if (Udp.remotePort() == remotePort) { //Sometimes the remotePort is different... I not sure why. memcpy((byte *)&in, packetBuffer, sizeof(_dataIn)); //Assign incoming value to local variable //Prepare the output struct Udp.beginPacket(remoteIp, remotePort); Udp.write((byte *)&out, sizeof(_dataOut)); Udp.endPacket(); } I presume this is the server end. Is that correct? Your "server" is responding to another device UDP request? What type device is on the other end, sending the request? The reason the remote port is different is most of the time is that the client will not normally use the destination port. All my clients use ports other than port 80 on the client end to make http requests. What is the value assigned to remotePort in your code? Maybe you should be using the port sent by the requesting device to reply to the request. edit: If your ethernet shield is exposed to the internet, it may not be your device making some of the requests. It could be a port scanner looking for open ports to exploit.
|
|
|
|
« Last Edit: February 09, 2012, 07:49:04 am by SurferTim »
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 19
Arduino rocks
|
 |
« Reply #7 on: February 09, 2012, 10:00:26 am » |
The remote machine is a windows machine that sends to arduino's port 8888, and is always one machine and always the same one, then the arduino reads the package, compose the answer and send it back to windows machine on port 8888.
_dataIn size is 1 byte, and I just check that "int packetSize = Udp.parsePacket();" not always return 1 byte
|
|
|
|
|
Logged
|
|
|
|
|
Miramar Beach, Florida
Offline
Faraday Member
Karma: 50
Posts: 3448
|
 |
« Reply #8 on: February 09, 2012, 10:36:44 am » |
OK. I see. Not sure I can help you with that. But it might help if you could be more specific about this? _dataIn size is 1 byte, and I just check that "int packetSize = Udp.parsePacket();" not always return 1 byte How often is "not always"? What does it return when it isn't 1 byte? 2? 9? edit: I just saw the comment in the original code. Between 10 and 12. And never less than 9?
|
|
|
|
« Last Edit: February 09, 2012, 10:44:02 am by SurferTim »
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 19
Arduino rocks
|
 |
« Reply #9 on: February 09, 2012, 10:47:35 am » |
You almost hit!... 10 Here you see only 8888 port incoming packages because I filtered all others before "167" are different traces inside sendUDP PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 8 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 8 PacketSize: 10 Port: 8888 Cycle time: 3 Cycle time: 3 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 7 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 6 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 7 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 7 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 7 PacketSize: 10 Port: 8888 Cycle time: 3 Cycle time: 3 PacketSize: 10 Port: 8888 Cycle time: 4 Cycle time: 1 Cycle time: 1 Cycle time: 3 PacketSize: 10 Port: 8888 Cycle time: 3 Cycle time: 1 Cycle time: 1 Cycle time: 3 PacketSize: 10 Port: 8888 Cycle time: 3 Cycle time: 1 Cycle time: 1 Cycle time: 3 PacketSize: 10 Port: 8888 Cycle time: 4 Cycle time: 1 Cycle time: 1 PacketSize: 10 Port: 8888 Cycle time: 5 Cycle time: 1 Cycle time: 1 Cycle time: 1 PacketSize: 10 Port: 8888 Cycle time: 3 Cycle time: 1 Cycle time: 1 Cycle time: 1 PacketSize: 10 Port: 8888 Cycle time: 3 Cycle time: 1 Cycle time: 1 Cycle time: 1 PacketSize: 10 Port: 8888 Cycle time: 4 Cycle time: 1 Cycle time: 1 Cycle time: 3 PacketSize: 10 Port: 8888 Cycle time: 3 Cycle time: 1 Cycle time: 1 Cycle time: 2 PacketSize: 10 Port: 8888 Cycle time: 3 Cycle time: 1 Cycle time: 2 Cycle time: 2 PacketSize: 10 Port: 8888 Cycle time: 3 Cycle time: 1 Cycle time: 1 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 7 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 7 Cycle time: 1 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 8 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 9 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 8 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 8 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 8 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 6 Cycle time: 3 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 6 PacketSize: 1 Port: 8888 Power: 1 Write: Ok167END Cycle time: 6 Cycle time: 3 PacketSize: 10 Port: 8888 Cycle time: 3 Cycle time: 1
|
|
|
|
|
Logged
|
|
|
|
|
Miramar Beach, Florida
Offline
Faraday Member
Karma: 50
Posts: 3448
|
 |
« Reply #10 on: February 09, 2012, 11:16:58 am » |
I'm not sure where that output came from. Have you tried the example code here? http://arduino.cc/en/Reference/EthernetUDPAvailableDoes that serial output help? I don't see a "Serial.begin(9600);" in the setup function tho. ??
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 19
Arduino rocks
|
 |
« Reply #11 on: February 09, 2012, 11:39:34 am » |
Arduino 1.0 UDP sample doesn't have the call to available, anyways, the available() call is embedded in parsePacket(). I will try in my next run. There's a Serial.begin(115200) Edit: It seems to solve the wrong packet size... now is always 1, except very seldom 0 sizes, like data arrives between parsePacket() and available() calls Let's see what happens after a few hours..... Edit2: Nop... even the wrong packet size appears again.... I think my next step is to allow only a few retries in the loop of death Maybe is some timing issue, the "print" fail rate is much more smaller than the no serial output version Edit3: SnIR::TIMEOUT is always 8 when the problem happend, rx light in the ethernet shield is always blinking ( http://db.tt/bgB1VQLK in the video 1 and 2 are stucked and 3 is running fine)
|
|
|
|
« Last Edit: February 09, 2012, 02:58:37 pm by motote »
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 98
|
 |
« Reply #12 on: February 09, 2012, 07:05:27 pm » |
Inside this loop....
while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) { if (W5100.readSnIR(s) & SnIR::TIMEOUT) { can you dump SnIR
HC
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Newbie
Karma: 0
Posts: 19
Arduino rocks
|
 |
« Reply #13 on: February 10, 2012, 02:55:21 am » |
HardCore, you mean dumping the result of W5100.readSnIR(s). no?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 98
|
 |
« Reply #14 on: February 11, 2012, 03:08:32 am » |
Same thing. I'm asking for the register to be dumped your asking for a function returning the register to be dumped.
I wanted to see the bottom 2 bits of SnIR whilst this was going on.
Because UDP does not require an 'ACK' there should be absolutely no reason it does not (SEND_OK), other than the external network cable is already busy/ no destination.
|
|
|
|
|
Logged
|
|
|
|
|
|