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.