Hi,
I am experiencing a problem connecting my Arduino mega to a raspberry pi via the usb. When I run firmata on the Arduino, the connection is guaranteed. When I run my own code on the Arduino, I run into problems connecting with the PI. Same code run on the Arduino, it has no problem with usb connection with a PC, but with the rasp pi usb I get the error that the port is temporarily unavailable. If I unplug the usb and plug it back in, then the connection occurs.
Any idea why my code has problems with the usb port on the pi, showing temporarily unavailable, but never a problem with a PC? Same hardware but running firmata, it always connects with the PI.
As well, there is never a problem interacting with the code on the Arduino using the Arduino ide serial monitor.
[code]
// This consists of
// #1 - parsing serial receive with start and end markers to two integers from format <7,180>
// #2 - writing the parsed integers to servos in the format of <pin number,degrees>
// #3 - incorporating NewPing library with 15 sensors, and writing the results to serial
// #4 - read analog pins
// Start #1
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
// variables to hold the parsed data
int servoNumber = 0;
int servoPosition = 0;
boolean newData = false;
// end #1
// my servo addition
#include <Servo.h>
Servo mys[20]; //Now we have 20 servos but only use 2-19 (ie 18 servos)
//
//Start #3 Ping code addition
#include <NewPing.h>
#define SONAR_NUM 4 // Number or sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
uint8_t currentSensor = 0; // Keeps track of which sensor is active.
NewPing sonar[SONAR_NUM] = { // Sensor object array.
NewPing(41, 42, MAX_DISTANCE), // name cm[0] left Each sensor's trigger pin, echo pin, and max distance to ping.
NewPing(43, 44, MAX_DISTANCE), // name cm[1] center
NewPing(45, 46, MAX_DISTANCE), // name cm[2] right
NewPing(47, 48, MAX_DISTANCE), // name cm[3] rear
//NewPing(23, 24, MAX_DISTANCE),
//NewPing(25, 26, MAX_DISTANCE),
//NewPing(27, 28, MAX_DISTANCE),
//NewPing(29, 30, MAX_DISTANCE),
//NewPing(31, 32, MAX_DISTANCE),
//NewPing(34, 33, MAX_DISTANCE),
//NewPing(35, 36, MAX_DISTANCE),
//NewPing(37, 38, MAX_DISTANCE),
//NewPing(39, 40, MAX_DISTANCE),
//NewPing(50, 51, MAX_DISTANCE),
//NewPing(52, 53, MAX_DISTANCE)
};
// end #3 newping addition============
// analog pin reading
int valAnalog0 = 0; // variable to store the value read A0
int valAnalog1 = 0; // variable to store the value read A1
int valAnalog2 = 0; // variable to store the value read A2
// end analog pin reading
int valpin50 = 0; // variable to store the read value
void setup() {
Serial.begin(115200);
// message for #1 Serial.println("This demo expects 2 pieces of data - two integers");
// Serial.println("Enter data in this style <1,180> ");
// Serial.println();
// my addition for servo array
for (int i = 2; i < 20; i++)
{
mys[i].attach(i);
mys[i].write(90);
}
// end my addition servo array
// Start #3 Ping code void setup addition
// already done Serial.begin(115200);
pingTimer[0] = millis() + 75; // First ping starts at 75ms, gives time for the Arduino to chill before starting.
for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
// end #3 ping code addition============
pinMode (50,INPUT); // sets pin 50 to read a digital input from Rasp PI pin 13 for decision making later in code
}
void loop() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
// showParsedData();
//
servoMove();
newData = false;
}
// #3 Ping code addition to void loop
{
for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
if (millis() >= pingTimer[i]) { // Is it this sensor's time to ping?
pingTimer[i] += PING_INTERVAL * SONAR_NUM; // Set next time this sensor will be pinged.
if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping (insurance).
currentSensor = i; // Sensor being accessed.
cm[currentSensor] = 0; // Make distance zero in case there's no ping echo for this sensor.
sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
}
}
// The rest of your code would go here.
// analog pin reading
valAnalog0 = analogRead(0); // read the input pin (IR front)
valAnalog1 = analogRead(1); // read the input pin (IR rear)
valAnalog2 = analogRead(2); // read the input pin (batvoltage)
// end analog pin reading
}
// end #3 Ping code addition to void loop
valpin50 = digitalRead(50); // read the input pin
}
//====#1========
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//=====#1=======
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars, ","); // get the first part - the string
servoNumber = atoi(strtokIndx); // my addition convert first part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
servoPosition = atoi(strtokIndx); // convert this part to an integer
}
//====#1========
void showParsedData() {
Serial.print("Servo Number ");
Serial.println(servoNumber);
Serial.print("Servo Position ");
Serial.println(servoPosition);
}
// start my addition for writing to servo
void servoMove() {
mys[servoNumber].write(servoPosition); //write servo position
// end my addition
}
//===#3====
void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
for (uint8_t i = 0; i < SONAR_NUM; i++) {
// Serial.print(i);
// Serial.print("=");
// Serial.print(cm[i]);
// Serial.print("cm ");
// writing JSON to serial
if (valpin50==1){
Serial.print ("{\"leftDistance\":");
Serial.print (cm[0]);
Serial.print (",");
Serial.print ("\"centerDistance\":");
Serial.print (cm[1]);
Serial.print (",");
Serial.print ("\"rightDistance\":");
Serial.print (cm[2]);
Serial.print (",");
Serial.print ("\"rearDistance\":");
Serial.print (cm[3]);
Serial.print (",");
Serial.print ("\"batteryVoltage\":");
Serial.print (valAnalog2);
Serial.println ("}"); // end of JSON
}
// end write JSON to serial
}
}
//====#3=====
void echoCheck() { // If ping received, set the sensor distance to array.
if (sonar[currentSensor].check_timer())
cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}
[/code]