Serial In on one port and command out on another..

Hi all,

A Little help if possible?

Im obviously missing something horribly obviouse here, but…

I have arduino nano, connected via USB at the mo, but will move to RF link shortly…

Problem is this…

I need to send data to the ardu, which is working, got my other bits and peices working fine, except, on a command to the ardu say “C1#” this then sends HEX data out on another pin in this case pin 7 tx.

so to recap serial in at 57000 baud working fine with all the commands from the PC, ardu controlling the other bits fine, need to output on another pin (7) HEX at 9600 baud…

here is my code, can anyone point out my stupidity?

//    S120#   servo 1 to position 20 degrees

#include <ctype.h> 
#include <Servo.h>
#include <SoftwareSerial.h>

//softserial setup

#define rxPin 8
#define txPin 7
SoftwareSerial CAMCOM=SoftwareSerial(rxPin,txPin);


//main serial in
#define SerialSpeed 57000
#define BufferLength 16
#define LineEnd '#'
#define PinServo1 2
#define PinServo2 3
#define PinServo3 4
#define DefaultServoPosition 90

//servo setup 
Servo servo1;
Servo servo2;
Servo servo3;
char inputBuffer[BufferLength];
//softserial rxtx
byte rx = 6;
byte tx = 7;
byte SWval;


void setup()
{
  //softserial setup

  CAMCOM.begin(9600);
  pinMode(rxPin,INPUT);
  pinMode(txPin,OUTPUT);

  // servo pins outputs
  pinMode(PinServo1, OUTPUT);
  pinMode(PinServo2, OUTPUT);
  pinMode(PinServo3, OUTPUT);    
  // attach servos and set servo-specific timing details
  servo1.attach(PinServo1, 600, 2100); // Azimuth servo
  servo2.attach(PinServo2, 700, 2300); // Elevation servo
  servo3.attach(PinServo3, 600, 2100); // back up servo
  // default servo positions
  servo1.write(DefaultServoPosition);
  servo2.write(DefaultServoPosition);
  servo3.write(DefaultServoPosition);  

  Serial.begin(SerialSpeed); 
}

// process a command string
void HandleCommand(char* input, int length)
{
  Serial.println(input);
  if (length < 2) { // not a valid command
    return;
  }
  int value = 0;
  // calculate number following command
  if (length > 2) {
    value = atoi(&input[2]);
  }
  int* command = (int*)input;
  // check commands
  // note that the two bytes are swapped, ie 'RA' means command AR
  switch(*command) {    
  case '1S':
    // servo1      
    servo1.write(value);
    break;
  case '2S':
    // servo2  
    servo2.write(value);
    break;
  case '3S':
    // servo 3
    servo3.write(value);
    break;

    // Cam Com 1  Power On/Off 
  case '1C':
      // action  Cam On
     SoftwareSerial.print("camon");
      Serial.println("CAM ZOOM CONTROL");    
      break;
   
   case '2C':
      // action Cam OFF  
      //SWprint('campower OFF');
      Serial.println("campower OFF bugger might be offf????");    
    break;

  default:
    Serial.println("unknown command");
    break;


  }  
} 

void loop()
{ 
  // get a command string from the serial port
  int inputLength = 0;
  do {
    while (!Serial.available()); // wait for input
    inputBuffer[inputLength] = Serial.read(); // read it in
  } 
  while (inputBuffer[inputLength] != LineEnd && ++inputLength < BufferLength);
  inputBuffer[inputLength] = 0; //  add null terminator
  HandleCommand(inputBuffer, inputLength);

  //soft serial output

}

note: i have used “camon” as a tester to see if the serial pin is actually doing something, which its not!..

many thanks.

regards,

Mike.

Ok Small update, there is ssomething coming off the pin, but its gobboldugook..

Checked the baud rates they are the same at 9600, but still rubbish.

EDIT:

The messed up message on teh rx side of things is constant, i.e. its the same characters on teh read side.

Also note, that i have 1 laptop tx'ing to the ardu, adn another laptop rx'ing off pin 7 of this makes any sence.

any ideas..

cheers

mike

Hi,
Looking at the code you posted (please use the code directive from the # icon in future)
You are only reading one byte of the incoming message before you start writing something.
You need to use:-
while (Serial.available() < n); // wait for input
where n is the expected length of the message. Then you need to read it in a byte at a time into your buffer.
How about the hardware? I assume you have TTL to RS232 converters on your soft serial I/O ports?

Best bet is if you strip out all the servo stuff and just post the code that reads a command in and writes it out. It could be that the servos are causing interference and crashing the arduino but get the serial in / out going first.

Hi Mike,

Again thanks for jumping to my rescue…
Ok Code posted using the widget…

//    S120#   servo 1 to position 20 degrees

#include <ctype.h> 
#include <Servo.h>
#include <SoftwareSerial.h>

//softserial setup

#define rxPin 8
#define txPin 7
SoftwareSerial CAMCOM=SoftwareSerial(rxPin,txPin);


//main serial in
#define SerialSpeed 57000
#define BufferLength 16
#define LineEnd '#'


char inputBuffer[BufferLength];
//softserial rxtx
byte rx = 6;
byte tx = 7;



void setup()
{
  //softserial setup

  CAMCOM.begin(9600);
  pinMode(rxPin,INPUT);
  pinMode(txPin,OUTPUT);

    
   

  Serial.begin(SerialSpeed); 
}

// process a command string
void HandleCommand(char* input, int length)
{
  Serial.println(input);
  if (length < 2) { // not a valid command
    return;
  }
  int value = 0;
  // calculate number following command
  if (length > 2) {
    value = atoi(&input[2]);
  }
  int* command = (int*)input;
  // check commands
  // note that the two bytes are swapped, ie 'RA' means command AR
  switch(*command) {    
  

    // Cam Com 1  Power On/Off 
  case '1C':
      // action  Cam On
     CAMCOM.print("TALK TO ME YOU BASTARD");
      Serial.println("CAM ZOOM CONTROL");    
      break;
   
   case '2C':
      // action Cam OFF  
      CAMCOM.print(value, HEX);
      Serial.println("campower OFF bugger might be offf????");    
    break;

  default:
    Serial.println("unknown command");
    break;


  }  
} 

void loop()
{ 
  // get a command string from the serial port
  int inputLength = 0;
  do {
    while (!Serial.available()); // wait for input
    inputBuffer[inputLength] = Serial.read(); // read it in
  } 
  while (inputBuffer[inputLength] != LineEnd && ++inputLength < BufferLength);
  inputBuffer[inputLength] = 0; //  add null terminator
  HandleCommand(inputBuffer, inputLength);

  //soft serial output

}

OK so if i type C1# in serial monitor ardu actions, adn out puts summet!..this in fact every time “U¥ýWa¿eu¿MaU¿{}YW}[w” on the serialmon of the other laptop

i do have a serial to USB converter on te RX laptop, as far as i can see the ardu outpt it TTL i think…im sure yuo can correct me…

This command 'while (Serial.available() < n); // wait for input

not sure where this should go?

still very early days for me yet but trying to learn…

any of this make any sence?

EDIT:

I should have mentioned that on command C1# is true, then the softserial outputs something like ‘81040702FF’ Hex data as a command for a periferal.

There are loads of commands but if i can get just one working the rest is a walk in the park…

thanks again.

regards,
Mike.

Hey Guys,

Anyone got any ideas, as i have been fannying around with this most of the night, and i still get garble on teh second laptop, uniform garble, but still garble…

its all wearing very thin now…

regards,

Mike.

How do you have the Rxing laptop connected, you may need to invert the signal going to the other device.

you could try sending some a character pattern that could indicate if the sequence is maintained on the receiving side:

For testing, why not simplify your sketch and just send a test message:

#include <SoftwareSerial.h>
#define rxPin 8
#define txPin 7
SoftwareSerial CAMCOM=SoftwareSerial(rxPin,txPin);

byte rx = 6;
byte tx = 7;


void setup()
{
  //softserial setup
  CAMCOM.begin(9600);
  pinMode(rxPin,INPUT);
  pinMode(txPin,OUTPUT);

}


void loop()
{
  // print all ascii characters
  for(char i = 33; i < 255; i++){  
    CAMCOM.print(i);
    delay(10);
  }
  delay(100);
}

Hi MEM,

I have the second laptop connected via a 9pD serial to usb converter.

So laptop 1 is connected to teh ardu via usb (at this time) i asume on pins 0/1 Hardware serial.

Pins 7/8 are softserial 7 out

pin 7 and Gnd are connected to the 9pD serial converter that returns to laptop 2 Hard serial is 57k soft serial is 9.6k.

As far as i can tell, teh serial is TTL, as the periferal has a converter board from laptop TTL serial so that teh cam understands real rs232, based on this assumption, i figure that laptop 2 outputs and inputs TTL rs232, so as far as ican tell, teh ardu outputs TTL rs232, therefore teh simple USB to 9pD converter shoudl do this....

PLEASE correct me if im wrong, been staring at this machine for FAAAARRRRRR too many hours LOL....

trouble is im on a time limit to sort all this and i sincerely appreciat any help you gurus can give....

I will try the simple test in a few mins...,'gotta run back to the workshops'

again many thanks, will report in 15 mins.

regards,

Mike.

Hi MEM,

Ok, run your code …this is what i get…

?~}>|{=zy<xaw;vu:ts9rq8po7nem6l
k5ji4hg3fe2d c1ba0`_/^].\ [-ZY,XW+VU*T
S)RQ(PO’NM&L K%JI$HG#FE"DC!BA @

the sqr boxes are spaces in the IDE monitor on laptop 2

looks like its trying real hard to do the right thing, but not quite…

Thoughts?

regards,

Mike.

I have the second laptop connected via a 9pD serial to usb converter.

as far as i can see the ardu outpt it TTL

Point is that while the arduino has TTL out and in, the 9pin D-Type does not, it outputs RS232 voltage levels of +/- 5 to 12V, with a space being high voltage.

You need some voltage translation (and signal inversion) between the arduino and the 9pin D-Type. Something like a max202 will provide both in the one chip.

Hi Mike,

SO i have it back to front, the output of the ardu is 5v TTL how ever the 9pD is lookng for 12v, hence teh right number of characters, just wrong ones?

so no matter what i do, its tx'ing properly , but when its being read back into laptop2 it will always be garbled, ...

so theoreticaly, i could use the usb converter the other way around, connect it to the output of the ardu so that when i send commands, the convertion i taking place, until i can get a max IC.

Sorry for all the newb questions, just need to fuly understand what i am doing.....

Thanks again.

regards,

Mike.

If the device you want to connect to uses a 9pin RS-232 connector then you need an adapter that converts from TTL (the output from the software serial) to RS-232. Many of the arduino parts suppliers sell these. I use one similar to this: http://www.nkcelectronics.com/rs232-to-ttl-converter-board-33v232335.html

Not only is the voltage wrong but the logic sense. So when the line is idle it is in the mark state the other side see it as active or the space state. Therefore the receiver can't detect the start of the character (start bit).

So no matter which way round you swap it you need to invert the logic. Couple that with the fact that feeding a negative signal into the arduino will damage it. I have herd of people doing what you have done and it has not damaged the arduino but by all rights it should have. As you are still getting the garbage characters it looks like it is working but you need to get the voltage and logic conversion in before it will work.

OK....Thanks for the heads up...

can i use a FTDI cale is as i have one for programming another ardu project?

clutching at straws really as time is of the essence here, and the powers that be, need this command thing working FAST...

Sincere thanks fro your help so far.

regards,

Mike.

Only if you get a TTL output from it which I doubt.
Best way for fast is just to invert the signal from the arduino using a transistor before it goes into the receivers laptop 9 pin D-Type. That’s just one transistor and two resistors.

The FTDI cable should work if you can plug the USB end into the device you want to connect to (for example the second laptop)?

That is assuming the FTDI does support TTL, perhaps a link to info on your cable will help clarify

Hi guys,

ok this is the unit:

http://www.sparkfun.com/commerce/product_info.php?products_id=9115

the FTDI 5v Basic

cant post the schemaic though....

make any sence?

regards,

Mike.

Yes that will work to feed the receiving laptop.

Well Guys,

In the usual more haste less speed fasion, some compete T**D plugged the FTDI in wrong....and toasted it.....

That would be me!!!!!!!!!!! the other boards are fine.....thank the gods of all things Arduino.......

Apart from ready to commit genocide, you guys have been superb help!!!

New FTDI should be with me in the morning, so will report back then...

again many thanks for taking the time to help..

regards,

Mike.

HI Guys,

Well The FTDI turned up in good fasion, Slapped it in place G-Mike suggested, whoooop…commands being sent…superb…

Went to trusted MAPLIN today (actually my wife did, tehe!) and bought the MAX232 chip…whipped a bit of vero into shape and voila…now reading the characters from ardu to laptop2 with no errors…

You guys are superb…

Plugged in the cam instead of Lap2 once i was sure that code was ending right…

now a wierd thing…

This might be obviouse or more fundamental…

Im using softserial '.print “8101040702FF2” ’

Perhaps you guys can point out my mistake…

the cam needs commands sent in hex, byte 1 is ‘81’ this is the talk to this camera command, the rest are serparate controls…
04 means control (not 02 enquiry), 07 means zoom, 02 means in tele extent, FF means end of packet…

ALL VISCA COMMANDS…

do i need to pull the line low at the start to signal an incoming packet to the cam, or do i need to configure that way teh packet is sent another way in softserial?

As the camera does not respond in any way…however if i use somthing like windmill comport, and put the hex in manually, she plays ball, zooms, goes on and off as expected…

any thoughts?

were sooo close i can smell it!!!

many thanks again…

regards,

Mike

the cam needs commands sent in hex,

If you send out:- '.print "8101040702FF2" '

You are actually sending out a sequence of ASCII bytes 8 is sent as a byte that is the equivalent of 56 in decimal or 0x38 in hex. 1 is sent as a byte that is the equivalent of 49 in decimal or 0x31 in hex. and so on.

So if you need to send out a hex byte you need to do something like serialPrint(0x38, HEX); I am not sure if this is supported by software serial. If it is not then you have to use a character variable char hex8 = 0x38; '.print (hex8);