0

need help in codes thread!
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

need help in codes thread!

by gr33nhorn on Sat Oct 04, 2008 4:46 pm

what went wrong in this sketch?
please enlighten me
Code: Select all | TOGGLE FULL SIZE
#include "math.h"
void setup()
{
  Serial.begin(9600);           // set up Serial library at 9600 bps
   double x , y, a ;
    x = -5;
    y = 5;
    a=atan2(y,x);
    Serial.print("arctan2 = ");
    Serial.println(a);
   
   
}

void loop()
{

}

gr33nhorn
 
Posts: 34
Joined: Sat Sep 20, 2008 4:36 pm

by westfw on Sat Oct 04, 2008 7:02 pm

Serial.println() doesn't support floating point arguments...
westfw
 
Posts: 1595
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

by gr33nhorn on Sun Oct 05, 2008 2:13 am

how to solve this problem?any example of simple code to explain solutions?
gr33nhorn
 
Posts: 34
Joined: Sat Sep 20, 2008 4:36 pm

by westfw on Sun Oct 05, 2008 3:12 am

You can try this. It seemed to work ok on a couple of test cases...

Code: Select all | TOGGLE FULL SIZE
/*
 * printfloat (double f)
 * print a floating point number, rounded to two decimal places.
 */
void printfloat(double f)
{
  int intpart, fracpart;
 
  intpart = (int)f;
  fracpart = ((int)(100.0*f + 0.5)) - 100 * intpart;  // grab two decimal places.
  Serial.print(intpart);
  Serial.print('.', BYTE);
  if (fracpart < 10) { // check if we need to explicitly handle leading zero
     Serial.print('0', BYTE);
  }
  Serial.println(fracpart);
}
westfw
 
Posts: 1595
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

by gr33nhorn on Mon Oct 06, 2008 2:23 pm

Code: Select all | TOGGLE FULL SIZE
((int)(100.0*f + 0.5)) - 100 * intpart


can you explain what this means?the mathematics don't seem to make sense...

thanks
gr33nhorn
 
Posts: 34
Joined: Sat Sep 20, 2008 4:36 pm

by westfw on Mon Oct 06, 2008 4:59 pm

Code: Select all | TOGGLE FULL SIZE
((int)(100.0*f + 0.5)) - 100 * intpart


Assume that f is 123.456.

100*f shifts the decimal point two places: 12345.6
+0.5 is for rounding: 12346.1
- 100*intpart removes the original integer portion that we already have: 46.1
and then the cast to (int) makes it an integer: 46

It seems to me it would have been clearer subtracting intpart first. I'm not sure why I didn't do that, but it was just something rattled off...
Code: Select all | TOGGLE FULL SIZE
(int) ( (f - intpart)*100 + 0.5)
westfw
 
Posts: 1595
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

by gr33nhorn on Tue Oct 07, 2008 1:54 pm

hey..thanks..i think i found out a much easier way...

arctan2(5, -5)=2.35619449rad

here's the code

Code: Select all | TOGGLE FULL SIZE
#include "math.h"
void setup()
{
  Serial.begin(9600);           // set up Serial library at 9600 bps
  double x , y ;
  int a;
    x = -5;
    y = 5;
    a=atan2(y,x)*1000;
    Serial.print("arctan2 = ");
    Serial.println(a);
   
   
}

void loop()
{

}


Code: Select all | TOGGLE FULL SIZE
arctan2 = 2356

[/code]
gr33nhorn
 
Posts: 34
Joined: Sat Sep 20, 2008 4:36 pm

by westfw on Tue Oct 07, 2008 5:00 pm

Now you've got the idea.
Personally, I don't trust function calls to properly cast their arguments into the form that I wanted them to have, so I'd do at least:
Code: Select all | TOGGLE FULL SIZE
Serial.println((int)a);

(in fact, arduino12 doesn't like the code the way you have it, complaining of:
Code: Select all | TOGGLE FULL SIZE
error: call of overloaded 'print(double&)' is ambiguous

Compilers tend to get fussier over time about detecting things that they think might be errors...)
westfw
 
Posts: 1595
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: need help in codes thread!

by gr33nhorn on Mon Oct 13, 2008 2:36 pm

thanks for your replies.i guess i wont be using the lastest version after you had said that. sign as i'm facing new problem now.
this is my edited code

Code: Select all | TOGGLE FULL SIZE
#include <math.h>
#define HEADER 0xff
void setup()
{
 
  Serial.begin(9600);           // set up Serial library at 9600 bps
  double x , y ;
  int a;
    x = -5;
    y = 5;
    a=atan2(y,x)*180/PI;
    Serial.print("arctan2 = ");
    char String[3] = {'HEADER','a','\0'};
    Serial.println(String);
   
   
}

void loop()
{

}


it turns out to be arctan2 = Ra rather than arctan2 = 0xff 135 which is the intended output.

let say i want the serial.print(String); results to be in hex.it is possible?meaning arctan2 = 0xff 87
gr33nhorn
 
Posts: 34
Joined: Sat Sep 20, 2008 4:36 pm

Re: need help in codes thread!

by gr33nhorn on Sun Oct 19, 2008 2:49 am

Online

Arduino rocks

Posts: 6


do i need to clear the buffer?
Today at 08:31:08 | Modify | Remove
hi..im still a noobie.im going to control a servo using arduino hardware uart. i will send 4byes of command packet and the servo will return 2btyes of response.
my question is since the buffer has only 128byte(default). do i need to clear the rx buffer if i keep sending and returning byte?what command is for clearing the buffer or i need to write a function for clearing?Sorry another noob question..does the return current; automatically clear the buffer?

there goes my code with full of bugs!help me point my error if possible thanks.
Code: Select all | TOGGLE FULL SIZE
#include <math.h>
#define HEADER 0xff
#define Speedlevel xxxx // hex value to represent the speedlevel
#define servoID xxxx // hex value to represent the servoID
#define position xxxx // any value from 0-255(byte/hex)that represents position

void setup()
{
 Serial.begin(9600);           // set up baudrate at 9600 bps
PosSend();
}

void loop()
{



}

void SendOperCommand(char Data1, char Data2)
{
char CheckSum;
CheckSum = (Data1^Data2)&0x7f;
serial.println(HEADER.BYTE);
serial.println(Data1.BYTE);
serial.println(Data2.BYTE);
serial.println(CheckSum.BYTE);
}

char PosSend(char ServoID, char SpeedLevel, char Position)
{
char Current;
SendOperCommand((SpeedLevel<<5)|ServoID, Position);
serial.read(); //read response packet?
Current =serial.read();
return Current;
}
gr33nhorn
 
Posts: 34
Joined: Sat Sep 20, 2008 4:36 pm

Re: need help in codes thread!

by gr33nhorn on Tue Oct 28, 2008 10:59 am

some questions regarding C again.

i'm using arduino to control this servo ,the protocol required 4-6bytes of data send to the servo and it will response back 2 bytes(Data1,Data2).


1)i called a BoundSet() in the void setup() that will send 6bytes to the servo,so must the data type be able to hold 6 bytes?

i.e
Code: Select all | TOGGLE FULL SIZE
 byte a;      // do i need a bigger capacity data type?
      a=BoundSet();


these codes are from the servo manual.
Code: Select all | TOGGLE FULL SIZE
/*------------------ Function relating to serial communication ----------------*/
void SendByte(char data); // Send 1 Byte to serial port
void GetByte(char timeout); // Receive 1 Byte from serial port



/******************************************************************************/
/* Function that sends Set Command Packet(6 Byte) to wCK module */
/* Input : Data1, Data2, Data3, Data4 */
/* Output : None */
/******************************************************************************/
void SendSetCommand(char Data1, char Data2, char Data3, char Data4)
{
char CheckSum;
CheckSum = (Data1^Data2^Data3^Data4)&0x7f;
SendByte(HEADER);
SendByte(Data1);
SendByte(Data2);
SendByte(Data3);
SendByte(Data4);
SendByte(CheckSum);
}


i replaced SendByte() by ie. Serial.print(data1,BYTE) and it works well


Code: Select all | TOGGLE FULL SIZE
/***********************************************************************/
/* Function that sends Boundary Set Command to wCK module */
/* Input : ServoID, *NewLBound, *NewUBound */
/* Return : 1 if succeed, 0 if fail */
/**********************************************************************/
char BoundSet(char ServoID, char *NewLBound, char *NewUBound)
{
char Data1,Data2;
SendSetCommand((7<<5)|ServoID, 0x11, *NewLBound, *NewUBound);
Data1 = GetByte(TIME_OUT2);
Data2 = GetByte(TIME_OUT2);
if((Data1==*NewLBound) && (Data2==*NewUBound)) return 1;
return 0;
}


2)can i replaced GetByte(TIME_OUT1) and GetByte(TIME_OUT2) with Serial.read()?

3)*NewLBound, *NewUBound...where should i call this 2 pointers?

4)since there is timeout1 and timeout2.Does this mean Data1 and Data2?

5)what do you think the code in void GetByte(char timeout)should be like? is it equilvalent to Serial.read()?
but Serial.read() doesnt seem to read the response from the servo or i need to write another function?


Code: Select all | TOGGLE FULL SIZE
/*************************************************************************************************/
/* Function that sends Position Move Command to wCK module */
/* Input : ServoID, SpeedLevel, Position */
/* Output : Current */
/*************************************************************************************************/
char PosSend(char ServoID, char SpeedLevel, char Position)
{
char Current;
SendOperCommand((SpeedLevel<<5)|ServoID, Position);
GetByte(TIME_OUT1);
Current = GetByte(TIME_OUT1);
return Current;
}


6)since the servo response with 2bytes.does this function GetByte(TIME_OUT1) reads 1 or 2 bytes?

7)why do we need to return current since we are only interested in sending the speedlevel,servoid and position?
gr33nhorn
 
Posts: 34
Joined: Sat Sep 20, 2008 4:36 pm

Re: need help in codes thread!

by westfw on Tue Oct 28, 2008 6:10 pm

1) no, the "return code" from the function doesn't need to be related in size to the amount of data sent.
2) Probably not. Serial.read() always returns immediately (with -1 if no data exists); but it looks like they want getbyte() to wait for data for up to TIMEOUT (milliseconds?)
3) I don't think your newbound parameters need to be pointers. I'm not sure what you're trying to do there.
4) I suspect TIME_OUT1 (which isn't used in the code pieces you posted, and TIME_OUT2 are values that represent the amount of time the servo controller might take to respond to a command, unrelated to Data1 and Data2.
5) GetByte(timeout) probably waits for up to timeout milliseconds for a serial character to be available. It would look something like:
Code: Select all | TOGGLE FULL SIZE
int GetByte(long timeout)
{
   unsigned long starttime = millis(); // when we started.
   while (millis() - starttime < timeout) {   // while we haven't timed out
      if (Serial.available() > 0) {  // See if there is data available
         return Serial.read();        // if so, return it to the caller.
      }
   }
   // We have exceeded the timeout without seeing any data.
   return -1;
}

6) The way I read it (do you have a link to the servo controller manual?), GetByte returns one byte for each call.
7) I dunno. Perhaps if things work, current will equal the new position. Perhaps the code is returned before the servo has finished moving, and indicates where the actual servo position is. Remember that the servo moves in timeframes on the order of 0.1 second, while the Arduino code runs in timeframes on the order of 0.000001 seconds...
westfw
 
Posts: 1595
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

Re: need help in codes thread!

by gr33nhorn on Wed Oct 29, 2008 12:01 pm

here's the link for the manual http://robosavvy.com/RoboSavvyPages/Rob ... s-manual...

hope there will be more people want to control these servos with arduino.

hope to see more reply from you westfw and others
..i will update this thread after i did my own homework again
gr33nhorn
 
Posts: 34
Joined: Sat Sep 20, 2008 4:36 pm

Re: need help in codes thread!

by gr33nhorn on Wed Oct 29, 2008 12:03 pm

gr33nhorn
 
Posts: 34
Joined: Sat Sep 20, 2008 4:36 pm

Re: need help in codes thread!

by gr33nhorn on Sat Nov 01, 2008 4:47 pm

thanks for the valuable code westfw...i have solved my problems :D
gr33nhorn
 
Posts: 34
Joined: Sat Sep 20, 2008 4:36 pm

Please be positive and constructive with your questions and comments.