Show Posts
Pages: [1] 2 3 ... 5
1  Using Arduino / Project Guidance / Re: How to make Reliable Serial communication on: November 11, 2012, 06:03:13 am
The txBuffer gets "nulled" just before the read loop starts, and in the "comma ==1" part, so that shouldn't be a problem. A problem that could occur is that the txBuffer doesn't contain numeric data. I guess it will make the atoi function throw an exception, but that is not handled (does Arduino support try - catch?).

True that this function has become too large to read properly. Splitting it up is put on the list. Nevertheless, I don't see big bugs that could disrupt a serial connection.

Well, thanks for the tips so far!
2  Using Arduino / Project Guidance / Re: How to make Reliable Serial communication on: November 09, 2012, 03:41:07 pm
Code down below. The "Serial" part at least. Showing the entire code would be quite big. I have to notice the Arduino only receives data, it doesn't write. Normally a message appears each second. But... since the message is triggered on the other system by sensors, it may happen it could be triggered twice. A rare occasion, but not impossible.

I haven't made the suggested start/stop character changes yet, it's just "as it is" right now. It wouldn't surprise me if there is something stupid inside hehe. One thing it does wrong already, is trying to convert the received data directly to work variables. This could cause an error when for example "atoi( <invalid number string> )" is called. But I don't think that would disrupt the communication though...

Resetting or skipping junk should be possible. In fact I changed the code earlier today so I could pull out the cable, re-insert, and just continue. Nevertheless, being disrupted means the machine misses a few camera-checks. As said, its not critical (we're not producing Rocket components). If it would happen a few times a week, well, I can live with that. If it happens once per few hours or so, it becomes a different story. I know you guys can't just tell me the chance on faults, as it really depends on the environment, wiring, the other device, and so on. But maybe some general hints? Also, I got to convince the Arduino isn't worse than a PLC for this particular case... unless the hardware (or Arduino Serial library) actually could be a problem source...


Not using a string library btw, just char buffers.
Code:
const int SERIAL_TIMEOUT = 15; // = 3 seconds time out
      int offline        = SERIAL_TIMEOUT;
      void  pollNVisionCommunication()
      {
          /**** 1. TIME OUT CHECK ****/
          // This function is called each 200 msec. Normally we receive something each 500 to 1400 msec.
          // If nothing was received for 3 seconds, either the machine conveyor belt has been
          // paused, or the communication is disrupted
          if (progState != PROGSTATE_PAUSED)
          {
              if (--offline < 0)
              {
                  offline   = 0;
                  progState = PROGSTATE_IDLE;  // Lost connection, or still waiting
                  // If the belt is still turning, it means we're not receiving (valid) messages
                  // Ifso, reset the connection
                  if ( !machineStopped )
                  {
                      Serial.println( "ERROR, Serial3 Reset" );  // Send diagnostic message via XBee
                      Serial3.end();
                      delay(25);
                      Serial3.begin( 9600 );
                      Serial3.flush();
                      offline = SERIAL_TIMEOUT; // 3 seconds              
                  } // Reset Serial 3                  
              } //
          } // belt not paused
          
          
          /**** 2. TIME OUT CHECK ****/
          // After each trigger (belt must move), the camera sends this string:
          //      0      1          2              3        4       5           6          7          8          9
          //    jobname,photoDelay,blisterDiscard,rowCount,charge,row1Result,row2Result,row3Result,row4Result,row5Result
          // for example
          //    "ProductX,250,23,2,4731ab-cx,1,1,1,0,0"
          //
          //  * The last 3 bits (row3/4/5) are optional and may not be included          
          char  txBuffer[MAXJOBNAMELEN+1];
          int   comma  = 0;
          int   indx   = 0;
          bool  jobOrChargeChanged = false;
          bool  validMessage  = false;

          for (int i=0; i<=MAXJOBNAMELEN; i++) txBuffer[i] = 0; // Clear tx buffer
          
          int avail = Serial3.available();
          while ( avail > 0 && indx < MAXJOBNAMELEN &&
                  comma < 10   // If the message has more than 10 comma's, its garbage for sure
                 )
          {
              char c = Serial3.read();

              if ( c == 13 || c == 10 || c == 0 ) break; /* terminator, exit receive loop */  else
              if ( c == ',')
              {   // In case of numeric data, convert here
                  // Otherwise, just reset the "index", and increment "comma" to fill the next field
                  if (comma==1)
                  {
                      cPhotoDelay = max( 0, min( 2000, atoi( txBuffer) )); // <-- ! goes wrong possibly
                      for (int i=0; i<=MAXJOBNAMELEN; i++) txBuffer[i] = 0; // clean
                  } else
                  if (comma==2)
                  {  
                      cDiscardBlst = max( 1, min(  atoi( txBuffer ), MAX_ROWBLISTERS-2 )); <-- ! goes wrong possibly
                  }
                  ++comma;
                  indx = 0;
              } else
                  switch (comma)
                  {
                    case 0  : { // Read chars for "JobName"
                                  if (cJobName[indx] != c) jobOrChargeChanged = true;
                                  cJobName[indx++] = c;
                                  break;
                              }    
                    case 1  : { txBuffer[indx++] = c; break; } // Read chars for PhotoDelay
                    case 2  : { txBuffer[indx++] = c; break; } // Read chars for Blister discard count
                    case 3  : { cRowCount = max( 1, min( 5, byte(c) - 48)); break; // single char rowcount }
                    case 4  : {
                                  if (cCharge[indx] != c) jobOrChargeChanged = true;
                                  cCharge[indx++] = c;
                                  offline         = SERIAL_TIMEOUT;      // Received something with at least 4 commas, thus a valid message probably
                                  validMessage    = true;
                                  break;
                              }
                    case 5  : { cRow1Fault = (c != 48); break; }
                    case 6  : { cRow2Fault = (c != 48); break; }
                    case 7  : { cRow3Fault = (c != 48); break; }
                    case 8  : { cRow4Fault = (c != 48); break; }
                    case 9  : { cRow5Fault = (c != 48); break; }
                  }
              // Next char
              avail = Serial3.available();
              if ( avail==0 ) // wait a short moment, maybe the host is still sending
              {
                  delay(150);
                  avail = Serial3.available();
              }
          }
          
          /**** 3. FINALIZE ****/
          // Change job in case the received jobName was different than the previous one
          Serial3.flush();          
          if (jobOrChargeChanged && validMessage)
          {
              resetJob( );
          }
          
      } // pollNVisionCommunication
3  Using Arduino / Project Guidance / Re: How to make Reliable Serial communication on: November 09, 2012, 11:12:02 am
>> achieve it by detecting and recovering from errors.
I added a time-out system that closed and re-open the connection when receiving nothing, or "junk". Detecting what is junk or not is a bit more complicated, but thats something I could work on.

I'm just wondering if the combination Arduino & a shortrange 2-wired RS232 cable is reliable in general. Of course, everything can be disrupted. And we're not talking about a critical application here. Nevertheless, it would suck if the controller has to recover 1 or more times a day, as it would miss a few things.

Some are suggesting to use a PLC for this program instead, but I don't think that would change eventual serial problems. Unless I made dumb bugs myself in the Arduino code of course.


>> Distance
The distance is minimal, the cable is 15 cm or something.

>> Checksum / start / stop characters
There should be indeed. Although the formatting options are limited, as the sender (a camera system) isn't fully programmable. Inserting start/stop characters is possible, although that's still doesn't make things waterproof of course. But at least its an easy start.

Thanks,
Rick

4  Using Arduino / Project Guidance / How to make Reliable Serial communication on: November 09, 2012, 06:24:18 am
Hey there,

It seems my Arduino sometimes stops receiving Serial data after a while (hours). My guess is a buffer overflow, or a leak in my code (writing outside the array index). So, got to improve my code, and eventually build a "reset" if we didn't receive anything for X seconds.

However, in order to create a buffer overflow or my code to crash, the Arduino must receive garbage of some sort I think. Having code to catch garbage is a must, but how to prevent garbage in the first place?
- Can a Serial connection (2 wires) be made garbage-free at all?
- What are typical factors to generate problems?
- Any software/hardware/wiring/general hints to prevent problems?

In other words, I want reliable communication, but I'm not sure if I'm using the right tools...

Some more info
* The hanging connection is Serial3 on a Arduino Mega, 9600 baudrate
* Serial(1) is used for a XBee
* Sender device sends messages every second. Equal length, but some content may differ.
* The serial wire is just a normal 9-pins connector & cable on one side. 2 wires from this cable are connected to a screw terminal on the Mega. No "heavy duty" cables are running nearby, although the Arduino is in a metal box, right next to a large packaging device. The Arduino itself is on a piece of plastic, on a DIN rail.

Cheers,
Rick
5  Using Arduino / General Electronics / Re: Arduino Mega, Screw (Terminal) it on: August 18, 2012, 09:28:11 am
Thanks for the hints guys!
Ordered the screw terminals, so that should do the job. I grouped all I/O in terminal blocks so that the wires could be bundled together rather than flying through the whole box. So one block for the LCD, another for encoders & buttons, et cetera.

There is already a prototype shield on top, since it has a handy foot for a XBee, but maybe using an extra larger blanc shield would be a good idea indeed to put on the resistors and such.

All in all the less different components, the better. If we have to replace parts or make an extra one over 2 years, it shouldn't become too much of a puzzle to find & build all components again. That's why I'm a bit wary with buying special shields. Screw terminal strips are available in any shop, but shields made for a special purpose... Still doubting a bit if I shouldn't just use a PLC, but it's a fun and learnful project (and cheaper) smiley-wink

Thanks,
Rick
6  Using Arduino / General Electronics / Re: Arduino Mega, Screw (Terminal) it on: August 17, 2012, 05:15:24 am
Just came across this:
http://www.digikey.com/product-detail/en/1-282834-2/A98075-ND/1826938
which were also mounted on this Arduino Mini board:
http://www.flickr.com/photos/36749491@N00/4796456051

So I suppose that would fit (am I right the pins on an arduino have 2.54mm distance between each?). That still wouldn't solve the problem with the double rows on the Mega, but it should give me enough terminals to do the job.

Can someone confirm these would fit? Thanks!
7  Using Arduino / General Electronics / Re: Arduino Mega, Screw (Terminal) it on: August 17, 2012, 02:21:32 am
Hi CrossRoads, thanks for the links.

Yes, a shield like that would be a good start (including the pins so I can mount another shield on top). Only problem is that these shields still do not provide terminals for the double row on the Arduino Mega (pin 22..52 I believe), while quite a lot of our wires also come from that "block". But now that I look at it... isn't there just an universal connector that exactly fits on it? That wouldn't give us screw terminals in that case, but at least you won't have to solder a lot of wires on the Arduino, creating spaghetti.

The encoder + socket is also a better start. The more we can group cables, the better. Then maybe put all the resistors together on a little panel, leading the wires further to the Arduino. Sorry if I sound a bit dumb, programmed a lot but never made an electronic device before!

Nice sites btw, I hope they ship in the Netherlands too!
8  Using Arduino / General Electronics / Arduino Mega, Screw (Terminal) it on: August 16, 2012, 09:33:02 am
Are there easy to attach screw terminals for the Arduino Mega? Or another robust type of system to (re)wire instead of fooling around with soldered wires all over the place? I saw a couple of Screw terminal shields, like this one
http://shop.vetcosurplus.com/catalog/images/VUPN5976-1.jpg

But the problem is that the Mega also has a double row of pins, as far as I know there aren't shields for that.

One option is to solder wires from the Arduino bottom to a screw terminal, then go further from that point. But maybe there are nicer plug-and-play solutions? One cool solution would be to have a connector+wires that can be plugged on the (double) rows of the Mega, and then on the other side on a string of screw terminals. I have little knowledge about such components though, so I need a push.


Maybe I should ask this in a different topic, but since its related to the wiring chaos... I have 3 encoders, each with 1 wire to the ground, 2 to pinA/B, and those 2 wires also go to the 5V via 10Kohm connectors. All in all, quite a mess. The goal is to put it all in a box later on, so having it ordered/grouped a bit would be nice. Tips?

Thanks,
Rick
9  Using Arduino / Installation & Troubleshooting / Re: FIO Gives Serial garbage on XBee after waking up on: April 05, 2012, 06:07:38 am
That's achieved with Cyclic Sleep modus I assume? A good suggestion, though there are some practical issues in my case.

AFAIK, Cyclic Sleep consumes a bit more than Pin Hibernate, and I really want to make to stretch the battery lifetime as long as possible. Second issue is that the microcontroller will wake up more often than than the XBee in the final version. For example, it measures the temperature each 2.5 minutes, and sends the average value after 20 minutes. All to save as much energy as possible...
10  Using Arduino / Installation & Troubleshooting / FIO Gives Serial garbage on XBee after waking up on: April 05, 2012, 03:45:10 am
Got some serial garbage coming out my FIO XBee, as soon as I wake up the XBee. The actual message being sent after that comes in fine though. This is what happens:
1- XBee slows (Pin Hibernate)
2- Arduino sleeps (Watchdog, power down)
3- After X times watchdog interrupts, the main cycle will wake up the XBee
4- When the XBee wakes up (pin output gets low), it sends something like ~.....)...... to another XBee, connected to the PC and monitored by X-CTU
6- ~2 seconds later the Arduino sends the actual message, will be received fine.
7- XBee is put asleep again (no garbage coming after the message or on shutdown btw)
8- Arduino puts itself asleep again

This does NOT happen when the I disable the "Pin Hibernate" sleep modus on the Xbee. Anyway, I tried to flush the Serial when waking up and just before putting the XBee asleep, but it still happens. I must also say that the garbage content isn't completely random. The length and the characters are almost the same each time.

Another little test. When I send no messages at all (no Serial.print), the same garbabe still occurs. Again, with sleepmodus disabled the clean stays clean though.

I guess waking up triggers some electro magic. I've read short bits about catching that with a resistor or something, but ifso, could someone give a bit more details about how to fix that on a FIO + XBee, using sleep and a battery?

---------------
Further details:
XBee Pro Series 1
Arduino FIO
Powered by a battery 3x2000 mAh, 3.7V  7.40Wh
* I don't have an extra USB cable to check if it still happens without the battery...

Cheers, Rick
11  Using Arduino / Programming Questions / Hibernating XBee resets the Arduino on wake-up on: November 24, 2011, 09:56:48 am
Anyone experience with Arduino + hibernating XBee? It seems that when I wake the XBee up after some time, the serial connection re-establishes and makes the Arduino reset. Correct?

I want to prevent this of course, so I could place a 120 Ohm resistor as described here:
http://www.arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection

But later on I'll be using an Arduino FIO... How to prevent resetting on that one? And before modifying the hardware, I just like to make sure this resetting is normal behavior. Here is a simple test-loop I made on a Duemilanove:
Code:
<program loop>
//Sleep
digitalWrite( sleepPin, HIGH ); // zzzz
delay( 15000 );
// Wake up call
digitalWrite( sleepPin, LOW );
delay( 8000 ); // Give it some time to wake up and find the other XBee
Serial.println( "Stinky cheese" );
delay( 8000 ); // Give it some time to send

<Restart the loop (and thus fall asleep again)>
This code will send the message to the other XBee, but resets after that.

About those 8-second delays, do I really need that much time to re-establish a connection and send something btw? The Arduino should run on a battery later on, so power-saving will be important. If I make the delays 7 seconds for example, the Arduino will also reset, but on top the XBee doesn't send the message anymore.
12  Using Arduino / Programming Questions / XBee Hibernate puts the Arduino asleep as well! on: November 18, 2011, 08:55:36 am
Hey there,
Time to hobby again with a XBee. Playing around with the Hibernate function on the XBee. It seems I can put the XBee asleep, but the Arduino main-loop stops as well, while it shouldn't. What I'm trying to do is:

* Arduino pin 8 is connected with XBee pin 9 for the sleep command
- in Setup(), set pin8 LOW, connect with the XBee and send "+++", followed by "ATSM 1"
- Set pin 9 of the XBee HIGH (=go to bed?)
- In the meanwhile, let the main loop switch on LED 13 shortly each 7 seconds

Nothing fancy, but when the XBee goes asleep (the green "Accosciate" LED on the shield goes off), the Arduino loop stops as well. At least, I don't see my LED toggling anymore.

If I keep pin 9 low, or put the sleep mode at ATSM 0 (sleep off), the main loop keeps working... It's as if the main loop is waiting forever, but for what (serial input?)? Should I stop the Serial connection as well when putting it to sleep (Serial.), and thus also restart with Serial.begin when I want to wake-up the XBee?
Code:
    void setup()
    {
        // Wake XBee, set it up
        pinMode( 13 , OUTPUT);     // LED
        pinMode(  8 , OUTPUT);     // Goes to XBee Hibernate pin 9
        digitalWrite(  8, LOW  );  // Power up
        digitalWrite( 13, LOW  );  //

        delay(250);       

        // Start serial comm, and send AT command to set the sleep modus
        Serial.begin( 9600 );       
        Serial.flush();
        delay(2100);
        Serial.print("+++");  // put the XBee in command mode
        Serial.flush();
        delay(1100);

        if (checkSerialForOk())
        {
           Serial.println("ATSM 1");
           Serial.flush();
           if (checkSerialForOk())
           {
              digitalWrite( 13, HIGH ); // Test if we received "OK"
           }
        }
       
        // Bedtime
        digitalWrite( 8, HIGH );

    } // setup
   
   
    void loop()
    {
delay(7000);
        digitalWrite( 13, HIGH );  // Just show we're alive
delay( 1000 );
        digitalWrite( 13, LOW );
// Later on I want to wake up the XBee each X time, and use the watchdog
// to put the Arduino asleep as well...
    }
Additional notes:
- Also when storing the sleep mode and skipping the entire AT-command setup will put both the XBee & Arduino asleep.
- Once asleep, the reset button doesn't work anymore... The green "power" LED keeps on though
- Using a Arduino duemilanove Atmega 328, XBee shield & Xbee shield. Nothing else.


Rick
13  Using Arduino / General Electronics / Re: Batteries, howto make a board that can run a year? on: April 16, 2011, 02:22:28 am
@Udo & Chaos
Thank you too!

If we want to go seriously for batteries, we need to dig a little bit deeper in the bare electronics. Not sure if the boss would like that (having one or two guys assembling custom boards every time costs time & money), but that at least I have arguments and guidelines now, thanks to you guys!

Ciao
14  Using Arduino / General Electronics / Re: Batteries, howto make a board that can run a year? on: April 15, 2011, 02:19:20 am
Those are useful tips! I'm going to sit comfortable & read through it.

As much as I would love to play around all day with boards, a little problem is that I'm doing it in the spare hours at work (I'm the only programmer here so there are always 100 things going on at the same time). So there isn't that much time to experiment. That's why we go for the Arduino: user-friendly & ready-to-go. Nevertheless, I'll read into this. Stripping the board or even using another options seems to be the only realistic solution, (If the boss still wants to go with batteries).

Thanks!
Rick
15  Using Arduino / General Electronics / Re: Batteries, howto make a board that can run a year? on: April 14, 2011, 05:47:34 am
Just found this:
http://www.faludi.com/2008/01/08/projects/
It includes a table with battery lifetimes related to Arduino & Xbee... not very hopeful. 117 hours at best. Well at least I don't have to feel I'm doing something incredibly wrong with the Arduino / XBee.

I don't have the hardware at hands now, but we could measure it again of course. We did that a year ago, and came roughly to the same conclusions as that table. Maybe a car/motor battery isn't such a weird idea after all! Or maybe the engineers shouldn't be that lazy and make sure netpower is withing reach everywhere smiley-wink

I wonder though, a device like a thermostat can run for a long time as well. It doesn't have a XBee, but yet it should regulate all the time, power a (dimmed) LCD, switch a relays. Are they doing something completely different then?
Pages: [1] 2 3 ... 5