Posts Tagged serial

def Python meets Arduino:

I write this article as an introduction to how the Python language can be used to talk to the Arduino board. In essence, what I do here is simple serial communication.

There is a program that I ve written for the Arduino board that does two simple things:

  • Reads the serial input.
  • Constrains the input to an integer between 0 and 179 and writes it to the servo motor.

The point at which python comes into play is when we, as users, provide the input. Although the Arduino software has its own Serial monitor which can be used to accomplish the same task, I am using python just as an alternative (this can be done in any other language too…python is just the easiest one). It might so happen that later on the Serial monitor and its functionality  might not be enough. You might be writing a larger application of which the serial communication is only a small part. In which case Python to the rescue…

So here is the scenario in short..

There is a servo motor attached to one of the pwm digital output pins of the Arduino and i have the python interpreter running on my computer. If you don’t have python installed on your comp you can install it from http://www.python.org/getit/. You will also need to install the pySerial module if don’t already have it. Open the python interpreter and type “import serial”. If you get an error install it from here http://sourceforge.net/projects/pyserial/

Next I upload the following code to the board:

Serial available() : returns the number of characters still left to be read

One more thing to remember, in serial communication information is received in terms of character bytes. That means even if we give the input as the number 123. The microcontroller receives it as character ‘1’, character ‘2’ and character ‘3’ respectively

The next statement takes care of this problem. The expression ” incoming_byte – ‘0’ “, subtracts the character ‘0’ from the character received  giving us an integer for e.g. ‘1’ – ‘0’ = 1 (integer). and adds it to 10 * sum (as calculated in the previous iteration). The final sum is constrained between 0 & 179 and assigned to the variable “angle”. Finally, the value of “angle” is written to the Servo.

Once the program is uploaded, I move on to python. I open the interpreter and type the following commands which are quite self explanatory:

So…thats it. One of the simple ways in which python can be used with Arduino.

Advertisements

, , , , , , , ,

3 Comments

Servo motor, Serial COM and 8051

In this project I control the angular position of a servo motor by using the serial communication ability of the 8051 microcontroller. To state it a bit more simply ..I control the angle by which the shaft of the servo motor rotates by pressing keys on my laptop. This project might be helpful to you, if you are planning to build a robotic arm someday and want to control it using your computer.

List of things I am using here:

  • 8051 microcontroller board.
  • A Servo motor.
  • Connecting wires.
  • Computer (..obviously :P)

The connections are really very simple. Choose any of the 32 input/output pins available on your microcontroller board and connect it to signal wire of the servo motor.

A servo motor has just three wire. One for Vcc, one for GND and a signal wire. They are generally colour coded. On the motor which I have, the colour codes are as follows:

  • Red – Vcc
  • Brown – GND
  • Yellow – Signal

In case you have any confusion regarding the colour codes for your motor,  it is always a good idea to just google the model of your motor and clear your doubt.

Once you are done with these connections, thats it  .. now all that needs to be done is to program the microcontroller.

In case you have used an Arduino board before, you might know that there already exists a library for controlling the Servo motor which makes the task trivial. But in the case of 8051 the it is a bit more complicated. Its easy but some math needs to be done.

The position of the servo motor depends on the width of the pulses that it receives on the signal wire.And these pulses need to have a time period of approximately 20ms. After doing some research on the web i found the “on” time of the pules required for various positions(.. applicable to my servo).

  • 0.388 ms – 0 degrees
  • 1.25ms – 90 degrees
  • 2.14ms -180 degrees

Next we need to create a loop that runs for a fixed amount of time and depending upon what is the width of the pulses required we can run it multiple number of times. The following code accomplishes it.

To give an example of how i use this code, say I want to set the angular position of the servo to 0 degrees. In that case i need to provide the pulses with the width of 0.388 ms.So i do it this way.

  • Set the output 1
  • Call set_timer(8) 8 * 50 = 400usec = 0.4ms ~0.388ms
  • Set the output 0
  • Call set_timer(400 – 8) // because 400* 50us = 20000us = 20ms.

And since the calling function is itself inside a loop that goes on forever unless you receive a character serially, we are able to provide the pulses every 20ms on the signal line that sets the servo at angular position zero.

The following function receives the angle that needs to be written on the servo and calls the set_timer() function shown above from within.

0,90 & 180 are the constants denoting different angles.

RI = 0 when no data is received  on the serial line and RI = 1 when data has been received successfully. So once data is received, it breaks out from the loop and exits to return to the main() function, as the write_pos() was called from main.

Now in the main function we do all the initializations, like setting the baud rate etc needed for serial communication.

To decide what value needs to be put in TH1 for a particular baud rate there is the following formula if the mode is 1:

TH1 = 255 – ((Crystal freq / 384)/baudrate).

Thats it then..when you load this program onto the microcontroller you ll be able to control the position of servo motor using the keys ‘1’, ‘2’ and ‘3’ on your keyboard.Check out the video here

Here is the final code:

//Servo motor position control using serial    communication

#include <reg52.h>
#include <stdio.h>

void write_pos(int position);
void set_timer(int x);

sbit servo_signal1 = P1^0;

int main (void){

unsigned char ch;

SCON = 0x50; //
TMOD = 0X22; //
TH1 = 244;   //
TR1 = 1;     //
TI = 1;      //
RI = 0;      //

while(!RI);
ch = SBUF;
RI = 0;

printf(“%c “,ch);
while (1){

switch(ch){
case ‘1’:
write_pos(0); // Set Servo position to 0 degrees
break;
case ‘2’:
write_pos(90); // Set Servo position to 90 degrees
break;
case ‘3’:
write_pos(180); // Set Servo position to 180 degrees
break;
default:
while(!RI); // wait till you get a valid input
RI = 0;

}
ch = SBUF;
printf(“%c “,ch);

}

}

void write_pos(int position){
int msec;
switch(position){
case 0:
msec = 8;
while(!RI){
servo_signal1 = 1;
set_timer(msec);
servo_signal1 = 0;
set_timer(400 -msec);}
RI = 0;
break;
case 90:
msec = 25;
while(!RI){
servo_signal1 = 1;
set_timer(msec);
servo_signal1 = 0;
set_timer(400 -msec);}
RI = 0;
break;
case 180:
msec = 40;
while(!RI){
servo_signal1 = 1;
set_timer(msec);
servo_signal1 = 0;
set_timer(400 -msec);
}
RI = 0;
break;
default:
;
}
}

void set_timer(int x){

int i;
// To run the loop given below once it takes approx 50us
// Since I have already used the timer 1 for serial communication, I use
// the timer 0 to give PWM signal to the servo motor.
for(i=0;i<x;i++)
{
TMOD=0x22;
TH0=0x0FF;
TL0=0x0D1;

TR0=1;
while(TF0==0);
TF0=0;
TR0=0;
}
}

, , , , ,

Leave a comment