Hi guys, I've got a little project whereby my arduino is connected to my PC through a USB hub, my sketch works fine when I upload the sketch.
However, I'm experiencing issues after turning my pc off and on again. If I re-upload the sketch after starting my pc, the sketch works fine which leads me to believe that this is an issue due to serial port initialisation or something along those lines.
The setup:
Python scripts running on my pc checks my email account to check for unread emails
Arduino waits for serial messages to act upon, when receiving a number > 0, the servo get's set to the upright position (It has a little flag attached)
Again, this all works unless I restart my PC and then it no longer functions at all, the arduino appears to not receive any of the messages.
ARDUINO CODE:
// Gmail Notifier
// Author: Will Price
// Date: Jan 2011
// Website: willprice94.blogspot.com
// Description:
//
// A simple sketch that waits for the number of unread messages to come over serial
// Use 'gmail_daemon' inconjunction for a physical mail notification system
// Macros
#include <Servo.h>
#define ServoPin 5 // The pin that the servo is connected to
// Variables
int msgs = 0; // Number of messages unread
//Setup Servo
Servo myservo;
//Initial Setup
void setup() {
pinMode(ServoPin, OUTPUT); // Set
Serial.begin(9600);
myservo.attach(ServoPin);
myservo.write(90); // Down position
}
//Loop
void loop() {
if (Serial.available() > 0) { // Waiting to read from serial, if the buffer > 0 BYTES then execute code
msgs = Serial.read();
if (msgs > 0) {
myservo.write(0); // Up position
}
else if (msgs == 0){
myservo.write(90); // Down position
}
}
}
PYTHON CODE:
#!/usr/bin/python2
# Author: Will Price
# Date: Jan 2011
# Import statements:
# - Feedparser - needed to extract mailcount
# - Serial - needed to send command to Arduino
# - Time - waiting for gmail to be read import feedparser, serial, time
import feedparser, serial, time
# Variables
checkPeriod = 60 # Time between check in seconds
username = "***"
password = "***"
label = " " #Label of folder to check no. of unread messages
# Define 'msgCount' function, returns number of unread messages (CREDIT TO:
def msgCount(uid, pwd, filter):
inbox = feedparser.parse("https://%s:%s@gmail.google.com/gmail/feed/atom%s" % (uid, pwd, filter))
return len(inbox["entries"])
# Code
while True:
# Serial port setup
com = serial.Serial("/dev/ttyUSB0",9600,timeout=0.25)
msgs = msgCount(username, password, label)
if (msgs > 0): # If number of unread messages is greater than 0, then tell the arduino
com.write("%c" % (msgs) )
# print "You have %d messages to read" % msgs # For debugging purposes
while (msgs > 0):
msgs = msgCount(username, password, label)
time.sleep(10)
com.write("%c" % 0)
# print "Inbox is empty" # For debugging purposes
com.close()
time.sleep(checkPeriod)
In the python code, what happens if you initialize the serial port before the while(true) and the close with com.close outside the loop? Eg: only initialize the serial port once.
Add LEDs (with current limiting resistors) and turn them on, one at a time at these points: start of setup(), after Serial.begin(), inside of loop(), and inside of your if-statement. This way you know at a glance what your Arduino is doing.
Add a pause after you open the serial port in python for 1-2 seconds. Each time the serial port is opened, the Arduino resets (unless you disabled DTR).
I'm not sure why a power cycle on the PC would put the Arduino is an unknown state, but at least use #1 to see how far it is getting.
when the pc is powered down, the hub shuts down for data only, the arduino's usb chip still sees power, when the pc starts up the arduino misses the poll for connected devices during the usb scan and the drivers don't load on the pc. I think you will find that the Arduino is not posting in device manager after restart of the computer. Try a direct connection to the PC USB port and do the reboot. The hub keeping the Arduiono powered may be making it not be seen by the hardware poll.
WizenedEE:
Um, what? If a computer is off, it doesn't provide power to USB.
I think ajofscott is referring to a self-powered Hub.
However, the suggestion may or may not hold up. If the Hub doesn't adhere to the USB spec, then it is might explain the issues. If it does adhere to the USB spec, than whether it stays powered while the PC is connected is moot. All devices should enumerate when requested. This is actually called out in the USB spec for cases where the PC might power cycle and the device doesn't (e.g the device itself is self-powered.)
ajofscott:
when the pc is powered down, the hub shuts down for data only, the arduino's usb chip still sees power, when the pc starts up the arduino misses the poll for connected devices during the usb scan and the drivers don't load on the pc. I think you will find that the Arduino is not posting in device manager after restart of the computer. Try a direct connection to the PC USB port and do the reboot. The hub keeping the Arduiono powered may be making it not be seen by the hardware poll.
Hello everyone, I'll get back to the other replies later today. However I know for sure this isn't the case as dmesg reports USB to FTDI and I dev is populated by ttyUSB0, so drivers being initialized on the PC isn't the problem.
To rule out the AVR or some unforseen glitch we have missed, try running the blink routine on a pin other than 13, reboot and see if the blink is still running. I'm chasing a USB induced reset. If the tiny's usb port is gone whack and is generating reset request which I thought was capacitively coupled, at least is on the Arduino it is. You could also monitor the reset pin with a DMM to see that it returns high after the PC restarts.
j514:
In the python code, what happens if you initialize the serial port before the while(true) and the close with com.close outside the loop? Eg: only initialize the serial port once.
Initialising the serial port once then running the sketch seems to have the exact same behavior
ajofscott:
To rule out the AVR or some unforseen glitch we have missed, try running the blink routine on a pin other than 13, reboot and see if the blink is still running. I'm chasing a USB induced reset. If the tiny's usb port is gone whack and is generating reset request which I thought was capacitively coupled, at least is on the Arduino it is. You could also monitor the reset pin with a DMM to see that it returns high after the PC restarts.
I can unplug the arduino after reboot, and then plug it back in and the sketch still doesn't work. the servo refuses to move to it's new position.
I just burnt a bootloader to a new chip and tried it on that with exactly the same behaviour observed. I'll add some LEDs etc to debug a little more thoroughly tomorrow and try and delve deeper into the issue.
After restart, the only way to get the sketch working again is to:
a) reupload the firmware to the Arduino
b) open the Arduinio IDE, open the serial monitor, send something, then close the serial monitor
EDIT: Running the blink sketch and restarting the computer works fine. The LED still blinks after startup (I used pin 3)
https://wiki.archlinux.org/index.php/Arduino
I run Arch linux and some distro-specific issues are noted here, I wonder if the incorrect baud rate is set at start up, If I run the script, when I have an email and the servo is meant to be set upright, the servo moves very slightly upwards, then almost immediately afterwards goes back to it's original state.
Swap the servo.attach and servo.write(90) such that you set the initial position before attaching to the pin, I have noted several instance in various other posts where the Servo object poutputs pulse rates out of range of a servo before any writes can be performed, If the servo is moving to a mechanical extreme it may be drawing enough current to interfere with the usb device.
// Gmail Notifier
// Author: Will Price
// Date: Jan 2011
// Website: willprice94.blogspot.com
// Description:
//
// A simple sketch that waits for the number of unread messages to come over serial
// Use 'gmail_daemon' inconjunction for a physical mail notification system
// Macros
#include <Servo.h>
#define ServoPin 5 // The pin that the servo is connected to
// Variables
int msgs = 0; // Number of messages unread
//Setup Servo
Servo myservo;
//Initial Setup
void setup() {
digitalWrite(1, HIGH);
pinMode(ServoPin, OUTPUT); // Set
myservo.write(90); // Down position
myservo.attach(ServoPin);
delay(2000);
Serial.begin(9600);
}
//Loop
void loop() {
if (Serial.available() > 0) { // Waiting to read from serial, if the buffer > 0 BYTES then execute code
msgs = Serial.read();
digitalWrite(2, HIGH);
delay(2000);
if (msgs > 0) {
digitalWrite(3, HIGH);
myservo.write(0); // Up position
}
else if (msgs == 0){
digitalWrite(4, HIGH);
myservo.write(90); // Down position
}
}
}
The LED on pin 1 lights up, when I run my debugging python script that just opens the serial port once, sends the number of messages over serial, then closes the port leaves the Arduino still with only the LED on pin 1 lit up, I think when the Arduino is receiving the serial message, the LED on pin 1 dims whilst it's receiving, then goes back to original brightness.
This code only works when I reupload the sketch after startup or send numbers through the serial monitor on the IDE.
Try remove the servo motor completely. Is there a difference in behavior? I'm wondering if the current draw of the servo is causing a droop problem at startup.
However, it occoured to me his sketch should still be running sitting and listening for a serial communication. As the OP stated he put it on the external power and it behaved the same. I have not tried serial communication in this manner with the Arduino. Are you using Xon Xoff or full handshake?
After trying lots of things I just couldn't get this to work, I opened virtualbox and fired up windows, flashed the code, restarted the pc, and voila, working flawlessly now. I'm fairly certain there is some program/library which isn't fully compatible in the Arch package. I'm going to look further into this and try and get Arch to produce reasonable code.
Thanks for all your help everyone, it was very handy and helped me rule out other possibilities.