Go Down

Topic: serial read from pololu trex (Read 413 times) previous topic - next topic

jwt666

Hi i wonder if someone can help i have an arduino uno connected to a pololu trex on a robot and am using serial comms for control which works fine. I am trying to read the motor currents using the serial write 0x8D and then using the serial read to try to get the value however nothing is being returned has anybody had any luck doing this. Thanks in advance.

AWOL

This is the "Programming" section.
It would be useful to see your program.
"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.

jwt666

Hi this is the code i am using
Code: [Select]

#include <SoftwareSerial.h>  // include serial library
#define TXPIN 8 // use pin 8 for serial transmit
#define RXPIN 9 // use pin 9 for serial receive
SoftwareSerial pololu(RXPIN, TXPIN); // use serial comms for speed control with pololu trex
int lmd; // left motor direction
int lms; // left motor speed
int rmd; // right motor direction
int rms; // right motor speed
int ch1; // radio control channel 1
int ch2; // radio control channel 2
int lmc; // left motor current
int rmc; // right motor current
int count = 0;

void setup()
{
  init();
  pinMode(RXPIN, INPUT); // make pin 8 input for serial comms
  pinMode(TXPIN, OUTPUT); // make pin 9 output for serial comms
  Serial.begin(9600); // set transmission speed for comms to xbee or laptop
  pololu.begin(19200); // set transmission speed for speed controller
  pinMode(5,INPUT); // make pin 5 input for rc
  pinMode(6,INPUT); // make pin 6 input for fc
}

void motor() // subroutine for sending info to speed controller
{
  pololu.write(lmd); // write left motor direction
  pololu.write(lms); // write left motor speed
  pololu.write(rmd); // write right motor direction
  pololu.write(rms); // write right motor speed
}

void loop()
{
  ch1 = pulseIn(5,HIGH,25000); // read rc servo pulse into channel 1
  ch2 = pulseIn(6,HIGH,25000); // read rc servo pulse into channel 2
  if (ch1 > 1450 && ch1 < 1550) // if servo pulse near to neutral
  {
    lms = 0; // left motor speed 0
    lmd = 194; // left motor fwd
  }
  if (ch1 <= 1450) // if servo pulse lower than neutral
  {
    lms = (ch1 - 1450) / -3; // speed scaling factor
    lmd = 193; // left motor rev
  }
  if (ch1 >= 1550) // if servo pulse higher than neutral
  {
    lms = (ch1 - 1550) / 3; // speed scaling factor
    lmd = 194; // left motor fwd
  }
  if (ch2 > 1450 && ch1 < 1550) // if servo pulse near neutral
  {
    rms = 0; // right motor speed 0
    rmd = 202; // right motor fwd
  }
  if (ch2 <= 1450) // if servo pulse lower than neutral
  {
    rms = (ch2 - 1450) / -3; // speed scaling factor
    rmd = 201; // right motor rev
  }
  if (ch2 >= 1550) // if servo pulse higher than neutral
  {
    rms = (ch2 - 1550) / 3; // speed scaling factor
    rmd = 202; // right motor fwd
  }
  count = count +1; // start count for serial print routine
  if (count == 20) // only serial print every 20 cycles to slow down serial display
  {
     Serial.print("lms= ");
     Serial.print(lms);
    if (lmd == 194)
    {
     Serial.println(" fwd");
    }
    if (lmd == 193)
    {
     Serial.println(" rev");
    }
     Serial.print("rms= ");
     Serial.print(rms);
    if (rmd == 202)
    {
     Serial.println(" fwd");
    }
    if (rmd == 201)
    {
     Serial.println("rev");
    }
    count = 0; // reset serial print routine count
  }
  motor(); // call motor subroutine
  pololu.write(0x8D0); //write motor current receive command
  char lmc = pololu.read(); // read in left motor current
  Serial.print("lmc = ");
  Serial.println(lmc);
}


AWOL

Quote
I am trying to read the motor currents using the serial write 0x8D
Code: [Select]
pololu.write(0x8D0);
Which is it supposed to be?
"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.

jwt666

Sorry about that its suppose to be 0x8D which was in my original program that i did not save and in writing the new one made that mistake

PaulS

Code: [Select]
void setup()
{
  init();

The init() function has already been called before setup(). Why are you calling it again?

Code: [Select]
  if (ch1 > 1450 && ch1 < 1550) // if servo pulse near to neutral
  {
    lms = 0; // left motor speed 0
    lmd = 194; // left motor fwd
  }
  if (ch1 <= 1450) // if servo pulse lower than neutral
  {
    lms = (ch1 - 1450) / -3; // speed scaling factor
    lmd = 193; // left motor rev
  }
  if (ch1 >= 1550) // if servo pulse higher than neutral
  {
    lms = (ch1 - 1550) / 3; // speed scaling factor
    lmd = 194; // left motor fwd
  }

The occasional use of else is a good idea. Only one of those blocks can be true on any given pass through loop. Once you've found the correct one, you can skip the rest, by using else appropriately.

Code: [Select]
  pololu.write(0x8D0); //write motor current receive command
  char lmc = pololu.read(); // read in left motor current

I want to know how much current you are using, and I want to know it NOW! NOW! NOW!.

I that realistic? How are you storing the -1 that the SoftwareSerial instance is getting in a char?

jwt666

Thanks for that Pauls you will have to excuse my ignorance I have been programming in c++ for only three weeks the time before that was 20 years ago and that was basic . I can understand your first two comments but don't understand the third surely the pololu should send the motor current info immediately to the arduino , also what do you mean by -1 ??? Any help is appreciated as I am a relative newbie to this but find it very interesting snd challenging.

AWOL

Your idea of "immediately" and the Arduino's differ vastly.
At 19200, a character takes over 500 microseconds to transmit.
"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.

jwt666

Ok I accept that , is there any way of say buffering the information as I do not want slow down the loop while waiting for it.
Cheers
James

PaulS

Quote
Ok I accept that , is there any way of say buffering the information as I do not want slow down the loop while waiting for it.

That happens automatically. You use the SoftwareSerial::available() method to see how much data has been buffered. Only when there is some data should you try to read it. If you try to read data that is not available, the read() method returns a -1. The return code from read is an int, which won't fit in a char.

If you use the available() method, and only read when there is data, the data is in the low order byte, which can be stored in a char, since the high order byte is KNOWN to be 0.

Keep in mind, though, that you should NOT be asking for current usage on EVERY pass through loop. It would be best to ask again only after receiving a reply from the last asking.

Go Up