Go Down

Topic: ARDUINO CODE PROBLEM! (Read 5407 times) previous topic - next topic

AWOL

Quote
Can't the PC see into my arduino

No, all the PC sees is the end of a length of wire with some ones and zeroes on it.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

rebecca

Can you tell me what i need to change then please? How can i make my pc see the readings from my arduino? All i want to do is see the multiple signals on my arduino displayed on a graph  :.

PaulS

There are a number of ways you could fix your code. You could send some specific value as a start or end of packet marker. The matlab program would wait for the start or end marker to appear ignoring anything that was not the start or end marker, then reading everything until the next start or end marker.

For example:
"|",L0, H0, L1, H1, L2, H2, ..., L6, H6, "|", L0, ...

The problem with this approach is that whatever value you use as start or end of packet marker may represent a valid low or high byte.

You could send the values as text, with start and end markers and delimiters.
"<287, 1000, 14, 299, 127, 943, 883><286, 876, ..."

The disadvantage to this approach is that converting the values to text takes time, and parsing the data on the receiving end takes time, too. The amount of data sent increases, too.

The advantage is that the start and end markers and delimiters are clearly separate values. The PC can probably parse and convert the values in next to no time, and the increase in data sent is typically about 100%. Sending the integer value 12 as two bytes takes two bytes. Sending it as a character string takes two bytes, so no increase. Sending the integer value 1023 as two bytes takes 2 bytes. Sending it as a character string takes 4 bytes, so a 100% increase. Since most values will be in the 10 to 999 range, there will be, on average, 3 characters per value (plus a delimiter) vs. 2 bytes, for an average of 4 bytes per value.

Clearly, though, the PC can then figure out how many values are in each packet.

rebecca

Hrmm, ive never used or even heard of start or end markers before! then again i have very little experience with arduino and matlab so im not surprised this is new to me..
Do u have an example, or if possible can you show me with the code i provided earlier a way of how to use these markers? I could really do with some help please

ArduinoM

in arduino playground I found this:
http://www.arduino.cc/playground/Interfacing/Matlab
witch points to this
http://www.mathworks.com/academia/arduino-software/arduino-matlab.html

Here is another more direct approach: (with example of reading data from a photocell)
http://robotgrrl.com/blog/2010/01/15/arduino-to-matlab-read-in-sensor-data/

D.

rebecca

The last website was quite useful!

Is there something im missing in this code though? I added the started&&ended to my code but im still not recieving what i need. If the code is right please tell me because that means i need to change something in my matlab insead. Any help is highly appreciated! Thanks a lot!

Code: [Select]
//ADC to Serial

char inData[10];
int analogPins [] = {0, 1, 2, 3, 4, 5, 6};    //pins to get pot voltage
int value;
boolean started = false;
boolean ended = false;

void setup()
{
  Serial.begin(9600); // opens serial port, sets data rate
}

void loop ()
{
   while (Serial.available() > 0)        //wait for request for data
   {
     for (int i = 0 ; i < 7 ; i ++)  //the 8-bit unsigned integer uses "pin" to iterate
     {
        Serial.println(analogRead(analogPins[i]),HEX); //prints line to dospay pin outputs
     }
     
     char data = Serial.read();
     if (data == '<')
     {
       started = true;
       value = 0;
       inData[value] = '\0';
     }
     else if (data == '>')
     {
       ended = true;
     }
     else if (started)
     {
       inData[value] = data;
       value++;
       inData[value] = '\0';
     }
   }
   
   if(started && ended)
   {
// Convert the string to an integer
int inInt = atoi(inData);
          Serial.println(inInt);
// Use the value

// Get ready for the next time
started = false;
ended = false;

value = 0;
inData[value] = '\0';
 
   }   
     
     
}

PaulS

The code you added (which is correct) to the Arduino was for reading serial data with start and end markers. I thought that your problem was needing to SEND data with start and end markers and delimiters.

rebecca

I need the arduino to read from the Razor only, but then i need my matlab to do the reading from my arduino not the other way around.
Which part of my program needs to be adjusted though? The one including my started&&ended?

WillR

#23
Mar 15, 2011, 10:23 pm Last Edit: Mar 15, 2011, 10:36 pm by WillR Reason: 1
Rebecca:

Both your PC and the Arduino are kinda myopic -- no they can't "see" each other unless you do something.

I assume that you want to "push" your data to the PC and the MATLAB program running on it. If so then you need to add a Level Changer -- and RS232C Voltage interface to the Arduino and hook it to your PC. tx --> Rx and vis-versa for the other two pins...

Now maybe you have a routine in MATLAB that treats the USB like a serial port -- but you never said which version of MATLAB.

So you need to WRITE the data to the serial port. Of course you can read the data from the PC if you want to send commands as well. But you don't have that in your program.... Of course packets help -- like people are suggesting -- but does MATLAB understand Packets?

If you write from the Arduino -- you receive at the PC.... It seems obvious I know -- but you need to make sure you do the correct things...

Now maybe you should spend a few minutes or a couple of hours writing a program specification, look at what you have achieved so far and supply the missing bits. It looks to me like you are "hacking" your way through this. This works for SuperProgrammer -- but most of us mortals need to plan.  :) No this isn't a lecture -- just pointing out the obvious... Step back, slow down and plan.


So, it sounds like the MATLAB program can read a stream of data from a device that connects through a port -- the serial port? But you did not supply those details either. Packets? Just the data? Some other way? Ethernet and UDP packets?

Is this how you are going to do the receive?

See the example...
http://www.mathworks.com/help/techdoc/ref/serial.fgetl.html

See serial Devices by scrolling down...
http://www.mathworks.com/help/techdoc/ref/f16-35614.html

It looks like you just need to set a "terminator" character (Say CR or Carriage Return) ... Discard the first group of values (since you don't know if it is small group, a large group, or just has just the right number of values) , use commas between values and receive a line...

Hope that is clear...

You can even sens a start and stop signal through Matlab and sit there and wait for it... easy peasy...

Now write a plan and a "Ping Pong" chart and you will see how to do the commands back and forth -- like a ping pong game 

send a command -->
<-- Return a answer
etc.
Just another Hacker

ArduinoM

#24
Mar 17, 2011, 10:25 pm Last Edit: Mar 17, 2011, 10:38 pm by ArduinoM Reason: 1
@WillR
Quote
I assume that you want to "push" your data to the PC and the MATLAB program running on it. If so then you need to add a Level Changer -- and RS232C Voltage interface to the Arduino and hook it to your PC. tx --> Rx and vis-versa for the other two pins...

Now maybe you have a routine in MATLAB that treats the USB like a serial port -- but you never said which version of MATLAB.



The arduino connected to a usb port is allready a virtual COM port. NO EXTRA HARDWARE NEEDED

@Rebecca
Have you tested the arduino code in the serialmonitor?
the program waits for a character from the COM-port (type anything in the serialmonitor and press ENTER) and then sends response
if serialmonitor is working, then see if MATLAB is listening on the right COM-port. I suspect that this is the issue here, I personally do not use Matlab but the principle is universal,no matter if the end program listening for the data is PROCESSING, JAVA, MATLAB, LABVIEW, EXCEL, VISUAL BASIC.......

To see what comport is in use, look at the serialwindowframe... (or the  IDE setup)
The serialwindow can only be open if Matlab is not listening.... only one program can listen to the serialport (USB) at a time.

D.

ps. Is your matlab program sending the arduino a characer to request sensordata?
If you do not want the matlab program to send a-ok signal for every to be receved data reading, then you might want to loose the
Code: [Select]
while (Serial.available() > 0)
and use a slight delay at the end of the loop instead....or not....
For send only... use just serial.print(...

rebecca

@WillR You're totally right as i checked with some other people and i dont need extra hardware..serial setup is fine. But there is something definitely wrong with my program because i fixed my matlab diagram and i know its correct, the only thing i have in the way is this code.
Maybe i should use something different to started&&ended? I dont know what else to change..all i want is for my matab to read 6 inputs from my arduino and "print" it onto my matlab graph. I didnt think it would be so complicated  :(

Code: [Select]
//ADC to Serial

char inData[10];  //minimum number of characters
int analogPins [] = {0, 1, 2, 3, 4, 5};    //pins to get pot voltage
int value;  //integer initialised
boolean started = false;
boolean ended = false;

void setup()
{
  Serial.begin(9600); // opens serial port, sets data rate
}

void loop ()
{     
     char data = Serial.read();
     if (data == '<')
     {
       started = true;
       value = 0;
       inData[value] = '\0';
     }
     else if (data == '>')
     {
       ended = true;
     }
     else if (started)
     {
       inData[value] = data;
       value++;
       inData[value] = '\0';
     }
     
   delay(250);
   
   for (int i = 0 ; i < 6 ; i ++)  //the 8-bit unsigned integer uses "pin" to iterate
     {
        Serial.println(analogRead(analogPins[i]),HEX); //prints line to display pin outputs
     }
     
   delay(250);
   
   if(started && ended)
   {
// Convert the string to an integer
int inInt = atoi(inData);
          Serial.println(inInt);
// Use the value

// Get ready for the next time
started = false;
ended = false;

value = 0;
inData[value] = '\0';
 
   }   
     
     
}

AWOL

Code: [Select]
char data = Serial.read();
     if (data == '<')
     {
       started = true;
       value = 0;
       inData[value] = '\0';
     }
     else if (data == '>')
     {
       ended = true;
     }
     else if (started)
     {
       inData[value] = data;


OK, assume "data" is not '<' and not '>', but what if there wasn't anything to read?
"data" would be -1.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

WillR

#27
Mar 22, 2011, 09:47 pm Last Edit: Mar 22, 2011, 10:00 pm by WillR Reason: 1
Rebecca:

See the part on parsing data.....

Maybe you want to send the whole line of six values as text separated by commas ... or something -- with just a terminator...
Matlab looks versatile enough for you to chose the method and then implement it on the Arduino...  The advantage of using text is that you don't have to worry about byte order. The disadvantage is that it's slower.

If you don't understand the comment about byte order -- send a string and sort out binary data later... (trust me)

Here is what I was trying to say: Assemble the 6 variables into a string, separate the variables with commas or semi-colons or whatever MATLAB likes, add a terminator (CR or LF, \n or whatever), send them to Matlab and let it turn them into values that are acceptable -- with a bit of math...

http://www.mathworks.com/help/techdoc/matlab_external/f62852.html#f123662

This is a coordination problem -- not a programming problem as such....

Both ends have to agree on a "data format" or protocol.... Note that their example accepts "," or ";" as the delimiter for the multiple values.


*********************************************************

Example -- Parsing Input Data Using textscan

This example illustrates how to use the textscan function to parse and format data that you read from a device. textscan is particularly useful when you want to parse a string into one or more variables, where each variable has its own specified format.

The instrument is a Tektronix TDS 210 two-channel oscilloscope connected to the serial port COM1.

  1.

     Create a serial port object -- Create the serial port object s associated with serial port COM1.

     s = serial('COM1');

  2.

     Connect to the device -- Connect s to the oscilloscope. Because the default value for the ReadAsyncMode property is continuous, data is asynchronously returned to the input buffer as soon as it is available from the instrument.

     fopen(s)

  3.

     Write and read data -- Write the RS232? command to the instrument using fprintf, and then read back the result of the command using fscanf. RS232? queries the RS-232 settings and returns the baud rate, the software flow control setting, the hardware flow control setting, the parity type, and the terminator.

     fprintf(s,'RS232?')
     data = fscanf(s)
     data =
     9600;0;0;NONE;LF

     Use the textscan function to parse and format the data variable into five new variables.

     C = textscan(a, '%d%d%d%s%s','delimiter',';');

     [br, sfc, hfc, par, tm] = deal(C{:});

     br =
             9600
     sfc =
          0
     hfc =
          0
     par =
         'NONE'
     tm =
         'LF'

  4.

     Disconnect and clean up -- When you no longer need s, you should disconnect it from the instrument, and remove it from memory and from the MATLAB workspace.

     fclose(s)
     delete(s)
     clear s

******************************************************

PS: Did your mother warn you about men that say "trust me"? She didn't -- ah well...
Just another Hacker

Go Up