Tuesday, 15 November 2016

Python + Arduino Project


Virtual Object Controller

  Recently I've been trying to learn a bit of Python and decided to build a project for fun.
This project has a simple objective: To control a virtual object using a set of potentiometers.

  By Connecting a set of potentiometers to an Arduino, this gave me the ability to manipulate two variables. I decided to manipulate the x-axis and the y-axis of a virtual box in Python.

  The Arduino's circuit is simple. It has 2 potentiometers and 2 LEDS which will have different light intensities based on how much the potentiometer is being turned.

  Here goes my attempt at explaining how the code works. *takes a deep breath*

  Let's take a look at the Arduino's code:
  The parts with the //(comment) is the explanation

//Moving a virtual object using potentiometers

int ledx = 5;   //Variables for LED pins
int ledy = 6;

void setup() {
  // put your setup code here, to run once:
Serial.begin (9600);                                                      //Initialize serial communication
pinMode(ledx, OUTPUT);
pinMode(ledy, OUTPUT);

void loop() {
  // put your main code here, to run repeatedly:
  int potx = analogRead(A0);                                         //declaring some variables to hold the                  int poty = analogRead(A1);                                           potentiometer reading
  int xval = map(potx, 0, 1023, 0, 50);                           //Here I am mapping the x-axis potentiometer
  int yval = map(poty, 0, 1023, 51, 101);                         from 0-1023 to 0-50. Smaller numbers will 
  int xled = map(potx, 0, 1023, 0, 255);                           help me manage the programming easier.
  int yled = map(poty, 0, 1023, 0, 255);                           Y-axis potentiometer is mapped to 51-101
                                                                                         because they need separate values to 
//0-50 is the range of values for x axis                            differentiate x and y axis. I'm also mapping 
//51-100 is the range of values for y axis                        the pot values to 0-255 for PWM for LEDS

//Varying light intesities based on the degree of movement of the x and y axis. (based on the potentiometer)

analogWrite(ledx, xled);
analogWrite(ledy, yled);

//Sending the potentiometer values to Python
Serial.println(xval);                                                     //Sending the values one by one to Python in
delay(10);                                                                      the form of string.


Now let's take a look at the Python side of the program: (# are for comments)

import serial                                               #Importing the necessary libraries for the code to work
from visual import * 

arduinoSerialData = serial.Serial('com6', 9600)        #Setting up serial communication, take note of
                                                                                     com port and baud rate (same with Arduino)

virtualObject = box(color = color.green, length = 3, width = 3, height = 3, pos = (0,0,0))

#Declaring an object to set up the shape. In my case, I'm using a box, the values in the brackets are
the parameters for the box. The 'pos' value is what we need to change dynamically, (x,y,z) axis. We don't have to bother with the Z axis in this case.

y = 0     #Declaring the variable used to change the Y-axis,  not sure why only y is needed, but the 
               code does not work without this.

while (1==1):        #Run everything in a loop
    rate(200)           #How fast it runs (tried 20, doesn't work too well)
    if (arduinoSerialData.inWaiting()>0):            #Check to see whether there's data
        value = arduinoSerialData.readline()          #Write the data in a variable called value
        data = int(value)                                           #Convert the string format data into an integer
        if (data < 51):                   #If the potentiometer reading is less than 51, the value received is
            x = data                          for the X-axis. Write the value into a variable called x.
        if (data > 50):                      #If the potentiometer reading is more than 51, the value received is
            y = data - 51                      for the Y-axis. Write the value into a variable called y. Minus the
                                                       value with 51 so that it starts from (0,0).

        virtualObject.pos = (-30 + x,-30 + y, 0)      #This is in charge of drawing the box itself. Notice 
                                                                              the variables in the position. This will enable                                                                                           updating of the x and y coordinates. I also start with
                                                                               (-30,-30) so that there's more space for the box to 
                                                                               move around.

Don't copy and paste the program from here. It might get messy. Instead, download it from my Google Drive folder.


No comments:

Post a Comment