Thursday, 9 February 2017

hello world for servo and vision - David Walsh

Servo Motors Hello World



Before starting it was important to understand how the servo motor works, the mbed controls the servo through the PWM (Pulse Width Modulation) where it sends out the signal in a pulse which will set the max position that the servo can move to. Servo motors are only able to go from 0 to 180 degrees. The signal length(pulse) determines this, from the diagram above it can be seen that for 0 the pulse width must be 1 milli second, 90 degree the pulse must be 1.5 milli second, 180 degree the pulse must 2milli second, these numbers can vary depending on which library that you’re using but generally servo motors pulse widths vary from 0.5 milli second to 2.5 milli second depending on the library been used.

Code for hello world:

#include "mbed.h"
#include "rtos.h"
#include "Servo.h"

Servo myservo(p21);
Servo myservo2(p22);
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

void led2_thread(void const *args)

{

       while (true)
    {
        led2 = !led2;
        Thread::wait(1000);
         myservo = 0.9;
         Thread::wait(1000);
         myservo = 0.0;
         Thread::wait(1000);
    }
}
void led3_thread(void const *args) 
{
 
    while (true)
    {
        led3 = !led3;
        Thread::wait(2500);
         myservo2 = 0.9;
         Thread::wait(2500);
         myservo2 = 0.0;
         Thread::wait(2500);   
    }

 }

int main() {
Thread thread(led2_thread);
Thread thread3(led3_thread);



    while (true)
     {
        led1 = !led1;
        Thread::wait(500);
     }
}
The above code uses threads to control the operation of the two servo motors, the code uses leds to visually tell what thread that is running. The two servos are running from 0 to 90 degrees but when the first servo turn in the queue it goes to 90 degree then it goes back into the queue and the other servo gets its chance and goes to 90 degree and he goes back into the queue, with the first servo then returns to zero when its turn in the queue comes again and the same with the second servo and continues this sequence if the Mbed is connected to them. It’s a simple hello world but shows that it easy enough to control the servos and run the simultaneously as they will be when mounted to the lamp where they will control the movement.

Serial Communication with Robo-Realm and Mbed

Serial communication was very frustrating to start with as my delay in the code was causing my all kind of problems when receiving serial data, it could not keep up with and the data kept over writing and what I was printing out was garbage. Eventually figured out the timing was wrong and needed to synchronise the robo-realm and mbed and now am receiving data at 250 milli seconds and printing on lcd screen matching the corresponding data been sent.

#include "mbed.h"
#include "C12832.h"   // Library for SPI based LCD

Serial pc(USBTX, USBRX);
C12832 lcd(p5, p7, p6, p8, p11); // Initialize lcd object with SPI pins

int main()
{
char buffer[128];
 while (true)
    {

    pc.gets(buffer,128);
    lcd.locate(0,15);
    lcd.printf("cogX:%s",buffer);   
    wait(0.1);
   }
}  


The code is straight forward, the top four lines are declaring libraries and the pins for the LCD screen and setting the serial connection. Main function, setting up a buffer array to 128 characters then setting up a while loop where pc.gets(buffer,128) this gets what’s on the serial line, lcd.locate is assigning the position on the lcd screen, lcd.printf() is printing what pc.gets() is holding and the wait for 0.1 second and continue in a while loop.  




This is screen shot of set up for serial, the green text between the and is what is been sent down on the serial line, the represents a space and represents line feed which puts it on the next line similar to carriage return. The [COG_X] is the data been sent out and its been set to be sent out every 250 milli seconds as can be seen in the screenshot.

Robo-realm Hello World
Serial communication is the main part of getting a hello world for this case study, the only other problem was to get the string that is being sent out serial to Mbed and convert this to an int, so that a compare function could be used to carry out a task and in this case, was to turn a led on if the centre of gravity was below a certain point and to turn it off it was above a certain point. First part was to get this working before putting it in threads.
#include "mbed.h"
#include "C12832.h"   // Library for SPI based LCD

Serial pc(USBTX, USBRX);
DigitalOut myled(LED1);
C12832 lcd(p5, p7, p6, p8, p11); // Initialize lcd object with SPI pins

int main()
{
char buffer[128];
int i;
 while (true)
  
    {

    pc.gets(buffer,128);
    lcd.locate(0,15);
    lcd.printf("cogX:%s",buffer);   
    wait(0.1);
    fgets (buffer, 128, stdin);
    i = atoi (buffer);
       
       if ( i < 200)
       
            myled = 1;
       
       else if ( i > 200)
       
            myled = 0;
       
}
}

The first part of the code is just initialising the libraries that will be used which are mbed.h and C12832.h which is the lcd screen library. The next part is initialising serial communication pins, led pin and lcd screen pins. Then the main function where first we have char buffer declaration of 128 characters, and declaring i as an int so we can change the string to int later in the code. Pc.gets() whatever is being sent over the serial port, lcd.locate is position for the lcd screen to display, with lcd.printf the function for displaying on the lcd screen. Fgets the the input from the char buffer,and stdin can be used as an argument for any function that expects an input stream as one of its parameters, like fgets or fscanf.
To change the buffer string to integers the atoi function is used parses the C-string str interpreting its content as an integral number, which is returned as a value of type int. the last bit of the code is turning on and off the led depending on which argument is met.



No comments:

Post a Comment