[solved] reading serial information from external source with Uno

My goal is to receive serial data from an external source while displaying the received (and recalculated) values live on my pc.

Just got my Uno this morning, and have been reading/tinkering since. I've tried on the softwareserial function connected to the ex.source and my pc via the USB which produced gobeldigoo so far. I'm not defeated yet but after reading a lot (searchterms "software" and "serial" provides plenty material) i'm wondering if it would be better to get a Mega or Due instead as they appear to support more serial ports?

I'm not sure how having an additional serial port differs exactly from using the IOports with softwareserial, so any advice on that would be appreciated.

Thanks for your help, i'm having a lot of fun so far, the day flew by.

Try the

Test: arduino to arduino serial using softwareSerial librar

at http://www.instructables.com/id/Test-arduino-to-arduino-serial-using-softwareSeri/#intro

If you have two arduino boards, I think Uno would work just as well.

thanks Jackwp, but i think our lines are crossed.

i've got the external source. It's a Foerster gradiometer with datalogger which outputs through serial com by some weird (but known) fixed binary format.

And why don't you just retrieve the signal directly on your pc, you might ask? I need a second input like a pushbutton to indicate when exactly to log the serial data. but thats step X. i'm focussing on the serial comm right now.

Ok. Then back to the original question. No, getting a board that has more serial ports will not help this case. Sorry. If your sending device could send a format that arduino can read, would be great. Does it have any options for that?

i've got the external source. It's a Foerster gradiometer with datalogger which outputs through serial com by some weird (but known) fixed binary format.

Does that mean you know the weird fixed binary format? Or are you looking for someone that knows that format?

I know the format that's not the problem.

It's just that i have not been able to get softwareserial to behave as i wish yet. I'll give it another try in the morning, i just want to make sure that i do not invest much time only to figure out later i need a different board.

Because i am unsure about the differences between using software serial on an Uno and having more than one serial port.

thanks

Then, I assume you have only one arduino board. So you can't test serial between two boards. What pins are you trying to use for the softwareserial testing ? In the URL I gave you it used pins 10 and pin 11, but should work with others as well.

I have used software serial several times on a Uno with no problems. The biggest difference between hardware and software serial is that the maximum baud rate is slower with software serial (56K if I remember right). What is the format of the data? Can you read the data into a buffer and decode/translate from the buffer?

Yes, just the one Uno board for now.

i cant find the exact definition of the format at this moment but this is the code to read it in Matlab:

[out count]=fread(obj,BA);
Bin=dec2bin(out,8);
BinRes(1:4)=Bin(1,5:8);
BinRes(5:11)=Bin(2,2:8);
BinRes(12:18)=Bin(3,2:8);
Dec=bin2dec(BinRes);
if Dec<= 78125
    Result=Dec/78125 * 10000;
elseif Dec>=184018 
    Result=-(262143-Dec)/(262143-184018) *10000;
else
    disp('faulty value detected. number out of possible range.');
    return;
end

But i’m not at that point yet.

Right now i’m trying the standard “SoftwareSerialExample” on ports 10 and 11. And using Termite/Serial Moniotor/Matlab to send and receive from the Arduino USB serial port, and the software serial via an 3rd party USB/serial converter. (portsettings matched to 57600/4800 in the example)
(Is it safe to directly use the comport on my PC, or is the voltage to high?)

The Arduino serial port does recieve the “Goodnight moon!” string.
The software serial recieves a string, but it is garbeled.

When 1 send a char trough the software serial, the Arduino serial does respond, but not with the same char. Sending the char “1” produces "g " (or “g[00]” on termite)
Sending “2” produces “3[00]”. sending “3” produces “f[00]”.

When i send char “1” trough the Arduino serial the software serial produces “g”. “2” gets “3”. “3” gets “f”.

So someting is wrong. As i said, this is just the default example, nothing altered in the code.

[update: found a bug, changed line 2 in the matlab code]

Did some more testing with the SoftwareSerial function. (still using the standard SoftwareSerialExample) (sorry if i'm getting off topic in this "project guidance" section, feel free to move it somewhere more appropriate)

I used some Matlab code to check in-output trough the arduino Com to the SoftwareserialCom.

(I checked the code using a virtual comportpair. And also using 2 usb2serial ports with nullmodemcable. Both checks worked fine, whatever i sent through 1 port I get out on the other. See the code below if you want to check.)

But if i try to use the arduino/software serial i get a different interger back as the one i sent. There is some pattern, but i'm not smart enough to figure out what the pattern means.

if i send (int8) 1 i get back 127 if i send 2 " 63 " 3 " 126 4 31 5 125 6 62

(note the 127-126-125 response on odd inputs)

Does anyone know whats going on here?

the matlab code i used to check: (tried setting both baudrates the same in the sketch, no difference)

function comtest 
SOSend=serial('Com6');
set(SOSend,'BaudRate',4800);
%set(SOSend,'BaudRate',57600);
fopen(SOSend);


SORec=serial('Com2');
set(SORec,'BaudRate',4800);
SORec.BytesAvailableFcnMode = 'byte';
SORec.BytesAvailableFcnCount=1;
SORec.BytesAvailableFcn =@DispData;
fopen(SORec);

fwrite(SOSend,1,'int8');
fclose(SORec);


fclose(SOSend);

function DispData(obj,event)
BA=obj.BytesAvailable;
[out count]=fread(obj,BA,'int8');
q=num2str(out);
disp(q)

I think I found the problem.

If I send the signal through the softwareserial port from a laptop that is NOT plugged in, the signal comes through correctly. So that would suggest the problem is with the GND connection somewhere.

Does anyone know a way to check where exactly the problem is, or how to fix this so i can use a desktop?

How are you powering the Uno? Is it battery, or from a wall plug? If it is a wall plug, and you can plug it in two ways, try plugging it in the other way.

I power by USB, as the computer is connected to be able to read the response sent to the Arduino serial port.

Ok, then how is the external source powered? What wires run between the Uno and the external source. ( 2 wires I suspect).

the external source was an usb to serial cable connected to the same computer as the Arduino USB cable. (when i got the wrong signals) the external source is the same usb to serial cable, but now connected to a laptop running on it's battery. (now its working)

I've got 3 wires coming from the usb to serial converter: Pin 5 (ground) to the arduinoUNO signal GND Pin 2 and 3 (Tx-Rx) to the arduinoUNO digital pins 10 and 11. (not exactly sure which to which, as there is a nullmodem cable between it as well due to the male/female connectors i have. I usually use trial and error to get them the right way round)

I guess 2 wires would suffice as i am only recieving data through softwareserial.

It sounds like the AC plugs were causing the problem. AC grounds not the same for both units. Is that what you think?

I am glad

(now its working)

AC grounds not the same for both units

It cant be that, as i had both the arduinoUSB and the external usb2serial plugged in the same computer. 2 USB ports side by side.

I sure am glad it's working. But it's more a workaround then a solution. Thanks for your suggestions.

I'm now tackling the binary conversion to something readable...

I think i got the conversion. I’ll post it here to be complete, but i seriously doubt anyone will be interested.
This is the code to read the serial response of a Foerster Ferex gradiometer (complete with commented out sections for debugging checks)

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX


int incomingByte = 0;  
int inputBuffer[4];
int Pos = 0;
long BitRes = 0;

void setup() {
  // initialize serial:
  Serial.begin(9600);

  
  mySerial.begin(9600);
  
  Serial.println("Setup ready.");
}


void loop() {

         if (mySerial.available() > 0) {
                 // read the incoming byte:
                incomingByte = mySerial.read();
                //Serial.write(incomingByte);
                //Serial.println(incomingByte);
                inputBuffer[Pos] = incomingByte;
                Pos++;
                //Serial.write(Pos);
                if (incomingByte == 3 || Pos == 4) {
                    if (Pos == 4 && incomingByte == 3) {

                       Pos=0;
                       
                       bitWrite(BitRes,17,bitRead(inputBuffer[0],3));
                       bitWrite(BitRes,16,bitRead(inputBuffer[0],2));
                       bitWrite(BitRes,15,bitRead(inputBuffer[0],1));
                       bitWrite(BitRes,14,bitRead(inputBuffer[0],0));
                       bitWrite(BitRes,13,bitRead(inputBuffer[1],6));
                       bitWrite(BitRes,12,bitRead(inputBuffer[1],5));
                       bitWrite(BitRes,11,bitRead(inputBuffer[1],4));
                       bitWrite(BitRes,10,bitRead(inputBuffer[1],3));
                       bitWrite(BitRes,9,bitRead(inputBuffer[1],2));
                       bitWrite(BitRes,8,bitRead(inputBuffer[1],1));
                       bitWrite(BitRes,7,bitRead(inputBuffer[1],0));
                       bitWrite(BitRes,6,bitRead(inputBuffer[2],6));
                       bitWrite(BitRes,5,bitRead(inputBuffer[2],5));
                       bitWrite(BitRes,4,bitRead(inputBuffer[2],4));
                       bitWrite(BitRes,3,bitRead(inputBuffer[2],3));
                       bitWrite(BitRes,2,bitRead(inputBuffer[2],2));
                       bitWrite(BitRes,1,bitRead(inputBuffer[2],1));
                       bitWrite(BitRes,0,bitRead(inputBuffer[2],0));
                       
                       //Serial.println(inputBuffer[0],BIN);
                       //Serial.println(inputBuffer[1],BIN);
                       //Serial.println(inputBuffer[2],BIN);
                       //Serial.println(BitRes,BIN);
                       //Serial.println(BitRes,DEC);
                       
                       if (BitRes <= 78125){
                         Serial.println(BitRes/78125 * 10000,DEC);
                       } else if (BitRes >= 184018) {
                         Serial.println(-(262143-BitRes)/(262143-184018) * 10000,DEC);
                       } else {
                         Serial.println("faulty value detected. number out of possibe range.");
                       }
                       
                    } else {
                      Pos = 0;

                    }
                }
             
         }
             
}

(I’ll test in on the real machine tomorrow, this is just going by the testing setup)
The matlab code to do the same is previously in this tread.

Solved over here: http://forum.arduino.cc/index.php?topic=189556.0