SC08A Servo Controller Can't get full movement of the servo

Autonomous Robot, Manual Robot, DC Motor Driver, Stepper Motor Driver, Servo, Multi PWM chip.....

SC08A Servo Controller Can't get full movement of the servo

Postby Ma'el » Mon Feb 15, 2016 2:28 am

Hi Guys,
Ma'el here; well I was doing a project using Arduino Uno and a SC08A. I tried to get a position of 180 degree position on a servo but simply couldn't. I followed the instructions in the User Documentation and I followed the sample code (link given below). However no avail; the most the servo goes is 120 degrees. Any idea what cause this problem. Thanks.

Awaiting your replies.


P.S: The servo that I am using is HD-3001HB (plastic Gears)

Link: http://tutorial.cytron.com.my/2012/06/2 ... g-arduino/
Ma'el
Greenhorn
 
Posts: 3
Joined: Mon Feb 15, 2016 2:20 am

Re: SC08A Servo Controller Can't get full movement of the se

Postby ZaM » Mon Feb 15, 2016 10:59 am

hi, i manage to make my servo hd-1160A turn 180 degree but only 120 degree for hd-9150MG, i use this code.

code:
Code: Select all
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

//Setup
void setup()
{
  mySerial.begin(9600);

  on_off_motor(0,1);  //activate all servo motor channels on SC08A

}

//Main loop
void loop() 
{
  for(int count = 0; count<8; count++)  //set 1st position, speed for all servo motor channels (servo motors), assignable speed value (1-100)
  {                                     //In position reporting operation, setting speed = 0 will cause the servo motor oscillates due to limitation of software position feedback
    set_ch_pos_spd(count+1, 7900, 50);  //set position = 7000, speed = 50
  }

  while(rd_current_pos(1) < 7900);  //wait untill the (position-100) is reached
 
  for(int count = 0; count<8; count++)  //set 2nd position, speed for all servo motor channels (servo motors), assignable speed value (1-100)
  {                                    //In position reporting operation, setting speed = 0 will cause the servo motor oscillates due to limitation of software position feedback
    set_ch_pos_spd(count+1, 100, 50); //set position = 4000, speed = 50
  }
 
  while(rd_current_pos(1) > 100); //wait untill the (position + 100) is reached
}

void on_off_motor(unsigned char channel, unsigned char on)
{
 /*****Activate servo channel command*****
 - 2 bytes involved
 - 1st byte: Mode + Servo motor channel
   eg:
       Ob 1 1 0 x x x x x;
         |Mode |Servo channel
 -the 3 MSB bits (110) is mode to activate servo channels
 -the last xxxxx can be assigned with value 0-16, where
  0 ---> activate all channels
  1 ---> activate channel 1
  2 ---> activate channel 2
  ....
  ....
  16 ---> activate channel 16
 - 2nd byte: On/off
   eg:
       0b 0 0 0 0 0 0 0 x
   x = 1 --> on selected and activated channel/channels
   x = 0 --> off selected or activated channel/channels
 ****************************************/
 
   unsigned char first_byte = 0;
   first_byte = 0b11000000 | channel; //make up 1st byte
   mySerial.write(first_byte); //send 1st byte use UART
   mySerial.write(on); //send 2nd byte use UART
}

void set_ch_pos_spd(unsigned char channel, unsigned int position, unsigned char velocity)
{
 /*****Position and Speed Command*****
 - 4 bytes involved
 - 1st byte: Mode + Servo motor channel
   eg:
     0b 1 1 1 x x x x x
        Mode |Servo channel
 - 3 MSBs (111) is mode for position and speed command
 - the last xxxxx can be assigned with value 1-16, where
   1 ---> select channel 1
   2 ---> select channel 2
   ....
   ....
   16 ---> select channel 16
 - 2nd byte: Position (High byte) higher 7-bit 
   eg:
     0b 0 x x x x x x x
 - the last xxxxxxx can be assigned with value 0 - 127
 - 3nd byte: Position (Low byte) lower 6-bit
   eg:
     0b 0 0 x x x x x x
 - the last xxxxxx can be assigned with value 0 - 63
   **2nd byte and 3byte is the position value when combined together into 13 bits position
 - 4th byte: Speed (0-100)
   eg:
     0b 0 x x x x x x x
 - the last xxxxxx can be assigned with value 0 - 100
 ************************************/
   unsigned char first_byte = 0;
   unsigned char high_byte = 0;
   unsigned char low_byte = 0;
   first_byte = 0b11100000 | channel; //make up the 1st byte
   high_byte = (position >> 6) & 0b01111111; //obtain the high byte of 13 bits position value
   low_byte = position & 0b00111111; //obtain the low byte of 13 bits position value

   mySerial.write(first_byte); //send the 1st byte
   mySerial.write(high_byte); //send the 2nd byte
   mySerial.write(low_byte); //send the 3rd byte
   mySerial.write(velocity); // send the 4th byte
}

unsigned int rd_current_pos(unsigned char channel)
{
 /*****Servo position reporting Command*****
 - 3 bytes involved (send 1 byte, received 2 bytes)
 - 1st byte: Mode + Servo motor channel (Send)
   eg:
     0b 1 0 1 x x x x x
        Mode |Servo channel
 - 3 MSBs (101) is mode for position reporting command
 - the last xxxxx can be assigned with value 1-16, where
   1 ---> select channel 1
   2 ---> select channel 2
   ....
   ....
   16 ---> select channel 16
 - 2nd byte: Position (High byte) higher 7-bit (1st received byte)
   eg:
     0b 0 x x x x x x x
 - Received value vary between 0 - 127
 - 3nd byte: Position (Low byte) lower 6-bit (2nd received byte)
   eg:
     0b 0 0 x x x x x x
 - Received value vary between 0 - 63
 **2nd byte and 3byte is the position value when combined together into 13 bits
 ******************************************/
   unsigned char first_byte = 0;
   unsigned char high_byte = 0;
   unsigned char low_byte = 0;
   unsigned int reading_position = 0;
   unsigned char buffer[2];
 
   first_byte =  0b10100000 | channel; //make up the 1st byte
   mySerial.write(first_byte); //send the 1st byte
   delay(200); //short delay for sending the data
 
//   while(!Serial.available()); //wait untill data received
//   for(int count = 0; count<2; count++) //store two bytes received in an array
//   {
//     buffer[count] = Serial.read();
//   }
   
   while(!mySerial.available()); //wait untill data received
   for(int count = 0; count<2; count++) //store two bytes received in an array
   {
     buffer[count] = mySerial.read();
   }
 
 //combine received high byte & low byte into 13 bits position value
   high_byte = buffer[0];
   low_byte = buffer[1];
   reading_position = high_byte;
   reading_position = high_byte<<6;
   reading_position = reading_position | low_byte;
   return reading_position; //return position value to the main
}

void initial_position(unsigned char channel, unsigned int position) //optional, if used, the RX pin of Arduino Mainboard should be connected to TX pin of SC08A
{
/*****Servo starting position Command*****\
- 3 bytes involved
- 1st byte: Mode + Servo motor channel
  eg:
    0b 1 0 0 x x x x x
       Mode |Servo channel
- 3 MSBs (111) is mode for position and speed command
- the last xxxxx can be assigned with value 1-16, where
   1 ---> select channel 1
   2 ---> select channel 2
   ....
   ....
   16 ---> select channel 16
- 2nd byte: Position (High byte) higher 7-bit 
  eg:
    0b 0 x x x x x x x
- the last xxxxxxx can be assigned with value 0 - 127
- 3nd byte: Position (Low byte) lower 6-bit
  eg:
    0b 0 0 x x x x x x
- the last xxxxxx can be assigned with value 0 - 63
**2nd byte and 3byte is the position value when combined together into 13 bits
*****************************************/
  unsigned char first_byte = 0;
  unsigned char high_byte = 0;
  unsigned char low_byte = 0;
  first_byte = 0b10000000 | channel; //make up the 1st byte
  high_byte = (position >> 6) & 0b01111111; //make up the high byte
  low_byte = position & 0b00111111; //make up the low byte
  mySerial.write(first_byte); //send the 1st byte
  mySerial.write(high_byte); //send the 2nd byte
  mySerial.write(low_byte); //send the 3rd byte
  delay(100); //short delay for sending the data
  while(!mySerial.available()); //wait untill data received
  while(mySerial.read() != 0x04); //wait untill value 0x40 is received for indication
}

ZaM
Moderator
 
Posts: 70
Joined: Tue Nov 23, 2010 4:16 pm

Re: SC08A Servo Controller Can't get full movement of the se

Postby Ma'el » Mon Feb 15, 2016 1:42 pm

Hi Friend,
Thanks for your reply; well I am using HD-3001HB motor, but I did the same code as you but no avail. Any ways thanks for the help my friend.
Ma'el
Greenhorn
 
Posts: 3
Joined: Mon Feb 15, 2016 2:20 am

Re: SC08A Servo Controller Can't get full movement of the se

Postby Ma'el » Mon Feb 15, 2016 6:34 pm

HI Guys,
I have found out hoe to do it I did got a full 180 Degree position from the Servo using the controller. What we all need to consider is that when we need to position the servo to any position we need to modify our 2nd (higher) and 3rd (lower) Bytes to special sizes (2nd as 7 bits and 3rd as 6 bits). Till now we have only been modifying the higher bit to 7 bit but we did not modified the lower bit to 6 bits. Below is the coding (original and modified) for solving this problem.

Original code (giving problem):

void SetPosition (unsigned char channel, unsigned int pos, unsigned char spd)
{
...
highBit = (pos>>6) & 0b01111111;
lowBit = pos &0b00111111;
...
}

Modified code (problem solved):

void SetPosition (unsigned char channel, unsigned int pos, unsigned char spd)
{
...
highBit = (pos>>6) & 0b01111111;
lowBit = (pos>>5) &0b00111111;
...
}



Thanks and have a nice day
Ma'el
Greenhorn
 
Posts: 3
Joined: Mon Feb 15, 2016 2:20 am


Return to Robot Controller

Who is online

Users browsing this forum: No registered users and 1 guest

cron