Pages: [1]   Go Down
Author Topic: Use serial monitor while COM port is in use?  (Read 769 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am trying to send a stream of numbers to the Arduino from an application on the PC (Simulink). I am having much trouble interpreting the number with the arduino. I've tried integers and float.

For debugging purposes, how can I use the serial monitor for debugging while the COM port is in use by Simulink? I get an "in use" error from either Simulink or Arduino, depending on which application starts first.

Also, How can I use serial.read () to interpret a 16 bit signed integer being sent by the PC?
Logged

Left Coast, CA (USA)
Online Online
Brattain Member
*****
Karma: 361
Posts: 17294
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

For debugging purposes, how can I use the serial monitor for debugging while the COM port is in use by Simulink? I get an "in use" error from either Simulink or Arduino, depending on which application starts first.

This is a restriction from the PC operating system, only allowing one application at a time to connect to a specific comm port.

Also, How can I use serial.read () to interpret a 16 bit signed integer being sent by the PC?

The Arduino serial.read() function can only deal (read) with one byte per read statement. If sending multbyte variables from a PC then your sketch code must read them as a series of individual bytes and then reassemble them into a int or long or float or array variable, as the case my be.

Lefty
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Lefty,

What is the process of assembling the two bytes (for an int) into an integer? is the array[] function necessary here?
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is the code I'm currently toying with

Code:
if (inbyte == '*') { // this means its the start of a number
             
             tsv = true; //
             startTime = millis(); // start time is now
             
             while (millis() - startTime < timeout && Serial.available() < 4) { // allow 4 at least bytes to fill the buffer
             }
           
             for (int i=0; i<2; i++) {
               b[i] = Serial.read();
             }
               
             
                 
             angval = int(b); // read an integer 
       
             if (tsv == true) {
               
               int angLED = (angval/90)*255; // prepare for the PWM signal
               // int angLEDpwm = abs(angLED); // absolute value for PWM LED // truncated?
               // check if the value looks write
               analogWrite(6,angLED); // debug
               blue.write(angval); // write servo?
               angval = 0; // reset?
               Serial.print(angLED);
               //delay(30);
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49339
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
             for (int i=0; i<2; i++) {
               b[i] = Serial.read();
             }
Are we to guess how b is declared?

Code:
             angval = int(b); // read an integer 
When there is a disagreement between the code and the comment, the code is always right. Except in this case, both are wrong. You can't cast an array to an integer.

Code:
               blue.write(angval); // write servo?
Don't you know what the code is doing? What exactly is the blue object? Blue is an adjective, not a noun.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This time I included the whole code, see below.
The comments aren't always up to date, especially when I'm trying stuff
b is a two byte array, how do I make an integer out of that array? do I need the array in the first place?

Quote
Don't you know what the code is doing? What exactly is the blue object? Blue is an adjective, not a noun.

of course not  smiley blue is a four letter word

Quote
// Control the small blue servo
// Brian Leach
// april 12 2011
// integer value from simulink. use the signed 16 bit integer from simulink with servo.write

#include <Servo.h>

Servo blue;

int ang; // create array to hold servo angle
int new_ang = 90;
int old_ang = 90;
byte b[2]; // byte array

void setup() {
   blue.attach(5, 1025, 1975); // servoName.attach(pin, min, max)
        Serial.begin(19200); // begin serial @ 19200 bits/sec
       
        pinMode(8,OUTPUT); // debug lights. red no serial
        pinMode(9,OUTPUT); // debug light green yea serial
        pinMode(6,OUTPUT); // output 6 LED
        //pinMode(5,OUTPUT); // output 5 servo
        byte homey = 90;
        blue.write(homey);  // set servo to mid-point
        delay(1000);;
}

void loop() {
 
  Serial.flush(); // clear the serial buffer before reading new data
  memset(b, '\0', 2);
  boolean tsv = false; // boolean to decide if the servo should be sent commands
  int angval = 0; // integer value of angle in degrees
 
   if (Serial.available() > 0) { // only loop the serial structure if its serialing

          digitalWrite(8,LOW);  // red off // light green if serial data, red if NO serial 
          digitalWrite(9,HIGH); // green on

          char inbyte = '\0'; // null?
          int timeout = 1000; // waits 1 second for a number
          long startTime = millis(); // now is the start time
          //delay(1); // try a delay
          while (millis() - startTime < timeout && inbyte != '*') { // this is the header character in the Simulink bloc. the loop waits for it
             inbyte = Serial.read(); // change the inbyte to the waiting byte
          }
 
          if (inbyte == '*') { // this means its the start of a number
             
             tsv = true; //
             startTime = millis(); // start time is now
             
             while (millis() - startTime < timeout && Serial.available() < 3) { // allow 4 at least bytes to fill the buffer
             }
           
             for (int i=0; i<2; i++) {
               b = Serial.read();
             }
                 
             angval = int(b); // read an integer 
             int new_ang = angval;
             
             if (old_ang != new_ang) { // if new angle equals old angle don't write anything
                if (tsv == true) {
               
                  int angLED = (angval/90)*255; // prepare for the PWM signal
                  // int angLEDpwm = abs(angLED); // absolute value for PWM LED // truncated?
                  // check if the value looks write
             
                  analogWrite(6,angLED); // debug
                  blue.write(angval); // write servo?
                  old_ang = angval; // reset?
                  Serial.print(angLED);
               
                }
             }
             //delay(.5);
          }
       }
       

        else {
          digitalWrite(8,HIGH); // red ON
          digitalWrite(9,LOW); // green OFF
          analogWrite(6,0); // servo lite OFF
        }
        delayMicroseconds(30);
}
       
     
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49339
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  Serial.flush(); // clear the serial buffer before reading new data
Throw away random amounts of as-yet-unread data. Sounds good to me. NOT.

Code:
          long startTime = millis(); // now is the start time
Look at the documentation for the millis() function. The return type is unsigned long, not long.

Code:
          while (millis() - startTime < timeout && inbyte != '*') { 
All variables in a conditional (the value returned by millis(), startTime, and timeout) should be the same type. You have three different types (unsigned long, long, and int).

Code:
             while (millis() - startTime < timeout && Serial.available() < 3) { // allow 4 at least bytes to fill the buffer
             }
           
             for (int i=0; i<2; i++) {
               b = Serial.read();
             }
Wait for there to be at least 3 bytes, so we can read both of them. Wrong.

Code:
             angval = int(b); // read an integer
You already know that this is wrong.

Code:
int new_ang = 90;
             int new_ang = angval;
Global and local values of the same name are rarely a good idea, especially when neither one is needed. The local variable is assigned the value in angval. Why not just use angval in the comparison that follows?

Code:
        delayMicroseconds(30);
Why? Wait a little while before looping and waiting for more serial data to arrive. Not needed, and is contributing to your timing issues, as is the Serial.flush() call.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 66
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the suggestions everyone. The solution to this problem can be seen at the page below.

http://arduino.cc/forum/index.php/topic,58460.15.html

Quote
If sending multbyte variables from a PC then your sketch code must read them as a series of individual bytes and then reassemble them into a int or long or float or array variable
I am still not clear on this process. Solved it for integers, but am still unsure about other data types

Brian
Logged

Pages: [1]   Go Up
Jump to: