Pages: [1]   Go Down
Author Topic: What IDE works best to read an integer from the Arduino and do a simple program?  (Read 558 times)
0 Members and 1 Guest are viewing this topic.
Northern California (by San Francisco)
Offline Offline
Sr. Member
****
Karma: 3
Posts: 258
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have an accelerometer hooked up to the Arduino and have it output the X-value as an integer using Serial.print(xValue);.  I want to take that X-value and output it on my laptop. I've tried to use the COM7 port on Windows, and ran into problems. So I tried using /dev/ttyS0 on Linux and ran into problems. So I took a look at Processing, and saw it was more difficult than I thought.

I need to spend more time on getting this to work. But my question is, which IDE should I chose to spend the time on? Will Windows, Linux (using C++) or Processing work best? Any suggestions?
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


Assuming your Arduino presents itself as COM7 you should be able to use any application that talks serial. But there can only talk one app to the serial port at a time (normally). Important is to have the coomunication parameters esp baudrate set the same on both sides.

Does the serial monitor of Arduino IDE work?
Which baudrate do you use?
Can you post the sketch you are using?

Rob
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Northern California (by San Francisco)
Offline Offline
Sr. Member
****
Karma: 3
Posts: 258
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the comments. I did make sure that the baud rates were the same. But the setup for simply getting an integer value from the Arduino seemed very complicated in Windows. So I'm hoping there is an easier way.

So far the code I wrote does not work quite right on the Windows side. Using the serial monitor, I can tell that it works right on the Arduino side.

Here's the code I used on Windows:

Code:
#include <Windows.h>
#include <iostream>
#include <MMSystem.h>
#include <stdio.h>
#include "stdafx.h"
using namespace std;



int main()
{
HANDLE hSerial; // set up COM7 as serial port for writing to Arduino

hSerial = CreateFile(_T("COM7"),
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);

if(hSerial==INVALID_HANDLE_VALUE){
if(GetLastError()==ERROR_FILE_NOT_FOUND){
cout<<"serial port does not exist.\n";
}
cout<<"some other error occurred.\n";
}
DCB dcbSerialParams = {0};

dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

if (!GetCommState(hSerial, &dcbSerialParams)) {
cout<<"error getting state.\n";
}

dcbSerialParams.BaudRate = CBR_9600;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;

if(!SetCommState(hSerial, &dcbSerialParams)){
cout<<"error setting serial port state.\n";
}
COMMTIMEOUTS timeouts={0};
timeouts.ReadIntervalTimeout=50;
timeouts.ReadTotalTimeoutConstant=50;
timeouts.ReadTotalTimeoutMultiplier=10;
timeouts.WriteTotalTimeoutConstant=50;
timeouts.WriteTotalTimeoutMultiplier=10;

if(!SetCommTimeouts(hSerial, &timeouts)){
cout<<"error setting timeouts.\n";
}

DWORD queueNum = 1;
SetupComm(hSerial, queueNum, queueNum);


int PotFlag = 0;
unsigned char ReadBuffer[1];
while (PotFlag == 0) {
DWORD BytesRead;
// PurgeComm(hSerial, PURGE_RXCLEAR);
ReadFile(hSerial, &ReadBuffer, 2, &BytesRead, NULL);
char firstByte = ReadBuffer[0];
int xValue = int(firstByte) * 256 + ReadBuffer[1];
cout<<"xValue: \t" << xValue <<"\n";
}
CloseHandle(hSerial);
}


Here's the code I used on the Arduino:

Code:
#define xInputPin 0
#define yInputPin 1
#define zInputPin 2

int xValue, yValue, zValue;
int zeroValue, change;
int oldX, oldY, oldZ;

void setup() {

      // start serial port at 9600 bits per second
      Serial.begin(9600);
     
      oldX = 0;
      oldY = 0;
      oldZ = 0;
     
      zeroValue = 325;    // the value at rest in any axis is about this number
      change = 10;

}

void loop() {

      xValue = analogRead(xInputPin) - zeroValue;
      yValue = analogRead(yInputPin) - zeroValue;
      zValue = analogRead(zInputPin) - zeroValue;

      if(abs(xValue - oldX) > change) {

      Serial.print(xValue);

      }
     
      oldX = xValue;
      oldY = yValue;
      oldZ = zValue;

      delay(10);

    }
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

the problem is in these 3 lines

Code:
ReadFile(hSerial, &ReadBuffer, 2, &BytesRead, NULL);
char firstByte = ReadBuffer[0];
int xValue = int(firstByte) * 256 + ReadBuffer[1];

You must check the value of the var BytesRead to see if there are really two bytes read, your code is too optimistic , Please change these 3 lines to

Code:
BytesRead = 0;
while (BytesRead == 0)
{
  ReadFile(hSerial, &ReadBuffer, 1, &BytesRead, NULL);
}
int xValue = ReadBuffer[0] * 256;

BytesRead = 0;
while (BytesRead == 0)
{
  ReadFile(hSerial, &ReadBuffer, 1, &BytesRead, NULL);
}
xValue += ReadBuffer[0];

This code reads in one byte at the time. Please note it blocks your app

Code can be made more generic to something like

Code:
int xValue = 0;
int BytesToRead  = 2;
while (BytesToRead > 0)
{
  do
    ReadFile(hSerial, &ReadBuffer, 1, &BytesRead, NULL);
  while (BytesRead == 0);

  xValue *= 256 + ReadBuffer[0];
  BytesToRead--;
}/code]

Hopes this helpes
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Northern California (by San Francisco)
Offline Offline
Sr. Member
****
Karma: 3
Posts: 258
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, I'll give those changes a try. I also need to add some code that checks if data was received. But the whole setup is pretty complicated. I wish there was a better way to get this one integer from the Arduino to my laptop than using this Windows ReadFile command. Maybe Linux or Processing. But I guess not.
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 212
Posts: 13531
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You might use another language e.g. python. For the script below you need to install python and the serial lib pySerial (IIRC). This small script is used to fetch lines from a serial port. These lines are split into fields (; = separator); and the complete line is send to a logfile.

Trick used here is to send integers as ASCII from the Arduino  -- Serial.print(x, DEC); -- A few more bytes may be used for communication but on the other hand all is readable. The Python serial class has a function readline() that hides all the difficult work. Recently I tinkered with gobetwino, took me a few hours to do what I wanted but also a powerful tool.

Code:
import sys, os, serial, datetime

def capture():

    print "Start capture"

    ser = serial.Serial(4, 115200, timeout=0)

    while (1):
        line = ser.readline()
        if (line != ""):
            #print line[:-1]         # strip \n
            fields = line[:-1].split('; ');
            ID = fields[0]
            TIME = int(fields[1])
            TIN = float(fields[2])
            TOUT = float(fields[3])

           
            # write to file
            filename = str(datetime.date.today()) + ".log"
            text_file = open(filename, "a")
            text_file.write(line)
            text_file.close()


""" -------------------------------------------
MAIN APPLICATION
""" 

print "Start Application"
print

capture()

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Northern California (by San Francisco)
Offline Offline
Sr. Member
****
Karma: 3
Posts: 258
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That's interesting. I'll take a look at Python and your code.

More generally, is there any way to send numbers as two-byte integers from the Arduino using the serial port? I don't want to send them as ASCII. I know that Serial.write(byte) will send one number. But when I tried to use Serial.write(buf, len) with buf being the address of a 2-byte char array, and len being 2, I got a compiler error.
Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 360
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You need to split the int (or use a union to tell the compiler to treat it as two bytes).

Code:
Serial.print(val >> 8, BYTE);
Serial.print(val & 0xff, BYTE);
Logged

Pages: [1]   Go Up
Jump to: