Pages: [1]   Go Down
Author Topic: strange corruption with "while (!Serial);" on Arduino Micro  (Read 780 times)
0 Members and 1 Guest are viewing this topic.
California
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Stock Arduino Micro, a 7-segment display with a backpack, and assorted libraries. The goal is to make a clock that goes into a CD-ROM bay in a PC and display the PC time. The Arduino runs its own time base, gets synced from the PC over USB once in a while.

This is the sketch:

Code:
/*
 *  Sync time from PC source over serial
 *  and show it on 7-segment LED display
 */

#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
#include <Time.h>
#include <TimeAlarms.h>

#define TIME_HEADER  "T"   // Header tag for serial time sync message
//#define TIME_REQUEST  7    // ASCII bell character requests a time sync message

Adafruit_7segment matrix = Adafruit_7segment();
const unsigned long DEFAULT_TIME = 1357041600;

void setup() {
  pinMode(13, OUTPUT);
  matrix.begin(0x70);
  Serial.begin(9600);

  // fake time
  setTime(DEFAULT_TIME);

  Alarm.timerRepeat(1, showTime);

//  while (!Serial);
  setSyncProvider(requestSync);
}

void loop() {
  if (Serial.available()) {
    processSyncMessage();
  }
  
//  showTime();
//  delay(1000);

  Alarm.delay(1000);
}

void showTime() {
  uint16_t timestr = 100 * hourFormat12() + minute();
  byte tick = (second() + 1) % 2;

  matrix.println(timestr);
  matrix.writeDigitRaw(2, 2 * tick);
  matrix.writeDisplay();
  digitalWrite(13, tick);
}

void processSyncMessage() {
  unsigned long pctime;

  if(Serial.find(TIME_HEADER)) {
     pctime = Serial.parseInt();
     if( pctime >= DEFAULT_TIME) { // check the integer is a valid time (greater than Jan 1 2013)
       setTime(pctime); // Sync Arduino clock to the time received on the serial port
     }
  }
}

time_t requestSync() {
//  Serial.write(TIME_REQUEST);
  return 0;
}

I could display time either using alarms (TimeAlarm.h), or plain old delays. As shown above, the code uses delays alarms, but the behavior is the same anyway.

To sync it up, I run this code on Linux:

Code:
#!/bin/bash

port="/dev/ttyACM0"

utc=`date +%s`
tz=`date +%:::z`
ltime=$(($utc + $tz * 3600))
echo "T${ltime}" > $port

If I uncomment the "while (!Serial);" line in the Arduino sketch, all hell breaks loose. The code often won't start; the display is frozen in whatever was the last state. Or it displays random segments on the display, as if it crashed. I reset the Arduino and nothing happens. After much reuploading and resetting, it eventually takes off, but that only lasts until the next reset. Many portions of the sketch are commented out, but the crash-and-freeze happens even with those parts added back in.

Once I commented out that line, the sketch works great.

Seeing as the line is probably not needed, I'll remove it permanently, but I'd like to understand why it fails like this so badly. Freezing - okay, that makes sense, maybe USB is not ready or something, but the total crashes where the display is corrupted???

The Micro is connected on USB to a laptop running Ubuntu 13.04.

The Micro and the display are probably okay. If I upload the "sevenseg" example that comes with the Backpack library, everything is running just fine.
« Last Edit: August 09, 2013, 07:08:17 pm by Florin Andrei » Logged


Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 652
Posts: 50869
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
but I'd like to understand why it fails like this so badly.
I'd like to understand why you included the line. All the samples that have that line CLEARLY indicate that it is needed ONLY for the Leonardo.
Logged

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19317
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Don't agree with that, PaulS.

See this page:

http://arduino.cc/en/Guide/ArduinoLeonardoMicro?from=Guide.ArduinoLeonardo

(This is linked to from the Micro product page).

On that:

Quote
No reset when you open the serial port.

Unlike the Arduino Uno, the Leonardo and Micro won't restart your sketch when you open a serial port on the computer. That means you won't see serial data that's already been sent to the computer by the board, including, for example, most data sent in the setup() function.

This change means that if you're using any Serial print(), println() or write() statments in your setup, they won't show up when you open the serial monitor. To work around this, you can check to see if the serial port is open like so:

Code:
// while the serial stream is not open, do nothing:
   while (!Serial) ;


Separation of USB and serial communication.

On the Leonardo and Micro, the main Serial class refers to the virtual serial driver on the board for connection to your computer over USB. It's not connected to the physical pins 0 and 1 as it is on the Uno and earlier boards. To use the hardware serial port (pins 0 and 1, RX and TX), use Serial1. (See the Serial reference pages for more information.)

It clearly mentions the Micro there.

So he's done the right thing, and that line shouldn't fail.
Logged

http://www.gammon.com.au/electronics

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

Global Moderator
Melbourne, Australia
Offline Offline
Brattain Member
*****
Karma: 511
Posts: 19317
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@Florin_Andrei - what version of the IDE do you have?

Please use code tags for code next time, not quotes or the "copy for forum" function in the IDE.

Read this before posting a programming question
Logged

http://www.gammon.com.au/electronics

Please post technical questions on the forum - not to me by personal message. Thanks a lot.

California
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@Florin_Andrei - what version of the IDE do you have?

Latest - 1.5.2. I share the sketchbook folder via Dropbox between Windows 7 and Ubuntu Linux 13.04 and I run the IDE on either computer. But it's mostly on Linux that I do my breadboard testing.

I will try different speeds for Serial.begin(), maybe that makes a difference. Again, it's no excuse for the nasty corruption, but maybe it's an enabling factor somehow.

Another weird thing: have you noticed I use hourFormat12() instead of hour()? Yeah, that's because the 24-hour function displays nothing at all. Even if I change the code from...

Code:
uint16_t timestr = 100 * hourFormat12() + minute();

...to...

Code:
uint16_t timestr = hour();

...so that only the hour is shown, all I get is a blank.

It's almost as if there's some subtle issue with one of the libraries, or something. I need to do more testing. I'll also try to bring this thread to the attention of the library authors, hopefully I won't waste their time.

I actually use the time library from pjrc: http://www.pjrc.com/teensy/td_libs_Time.html

Quote
Please use code tags for code next time, not quotes or the "copy for forum" function in the IDE.

Apologies for making a mess, I fixed it.
Logged


California
Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I've downgraded from 1.5.2 (beta) to 1.0.5 (stable). Same issues.

I've reduced the sketch to the minimal size that still demonstrates the problem:

Code:
void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(9600);
 
//  while (!Serial);
}

void loop() {
  digitalWrite(13, 1);
  delay(100);
  digitalWrite(13, 0);
  delay(100);
}

This version works fine. If I uncomment the "while (!Serial);" line, it freezes. Comment it back out, and it starts blinking again.

I've changed the serial speed to 115200 - same symptoms.

Again, this is on an Arduino Micro, connected via USB to a laptop running Ubuntu Linux 13.04 64bit.
Logged


New Jersey
Offline Offline
God Member
*****
Karma: 2
Posts: 537
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried this on my Micro.  I'm have IDE 1.05 on a Mac.  The sketch stays stuck in the while loop until I open my serial monitor, it's not 'freezing'.  Then exits the while loop and moves on.  I ran the sketch below and the LED blinks slowly until I open my serial monitor then it blinks fast.

Code:
void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(9600);
 
  do {
    digitalWrite(13, 1);
    delay(500);
    digitalWrite(13, 0);
    delay(500);
  } while (!Serial);
}

void loop() {
  digitalWrite(13, 1);
  delay(100);
  digitalWrite(13, 0);
  delay(100);
}

On my Leonardo I usually use this code so it only loops for 8 seconds and then moves on:
Code:
while (!Serial && millis() < 8000) {}
Logged

Pages: [1]   Go Up
Jump to: