Hi. I used an arduino uno and connected to python using vPython. I have used a color sensor and an HC_SR04 sensor. What it should do is detect distance from the sensor to the target in the real world and also detect the color of the target in real world & then accordingly make changes in the virtual world.
This is my arduino code:
int s0= 8;
int s1= 9;
int s2= 10;
int s3= 11;
int out= 12;
int trigPin=6; //Ultrasonic Sensor Trig pin connected to Arduino pin 6
int echoPin=7; //Ultrasonic Sensor Echo pin connected to Arduino pin 7
float pingTime; //time for ping to travel from sensor to target and return
float targetDistance; //Distance to Target in inches
float speedOfSound=776.5; //Speed of sound in miles per hour when temp is 77 degrees.
int data=0; //This is where we're going to stock our values
void setup()
{
pinMode(s0,OUTPUT);
pinMode(s1,OUTPUT);
pinMode(s2,OUTPUT);
pinMode(s3,OUTPUT);
pinMode(out,INPUT);
pinMode(trigPin, OUTPUT); //Ultrasonic Trig Pin is an output
pinMode(echoPin, INPUT); //Ultrasonic Echo Pin is an input
Serial.begin(115200); //intialize the serial monitor baud rate
digitalWrite(s0,HIGH); //Putting S0/S1 on HIGH/HIGH levels means the output frequency scalling is at 100% (recommended)
digitalWrite(s1,HIGH); //LOW/LOW is off HIGH/LOW is 20% and LOW/HIGH is 2%
}
void loop() //Every 2s we select a photodiodes set and read its data
{
digitalWrite(s2,LOW); //S2/S3 levels define which set of photodiodes we are using LOW/LOW is for RED LOW/HIGH is for Blue and HIGH/HIGH is for green
digitalWrite(s3,LOW);
GetData(); //Executing GetData function to get the value
digitalWrite(s2,LOW);
digitalWrite(s3,HIGH);
GetData();
digitalWrite(s2,HIGH);
digitalWrite(s3,HIGH);
GetData();
digitalWrite(trigPin, LOW); //Set trigger pin low
delayMicroseconds(2000); //Let signal settle
digitalWrite(trigPin, HIGH); //Set trigPin high
delayMicroseconds(15); //Delay in high state
digitalWrite(trigPin, LOW); //ping has now been sent
delayMicroseconds(10); //Delay in low state
pingTime = pulseIn(echoPin, HIGH); //pingTime is presented in microceconds
pingTime=pingTime/1000000; //convert pingTime to seconds by dividing by 1000000 (microseconds in a second)
pingTime=pingTime/3600; //convert pingtime to hourse by dividing by 3600 (seconds in an hour)
targetDistance= speedOfSound * pingTime; //This will be in miles, since speed of sound was miles per hour
targetDistance=targetDistance/2; //Remember ping travels to target and back from target, so you must divide by 2 for actual target distance.
targetDistance= targetDistance*63360; //Convert miles to inches by multipling by 63360 (inches per mile)
Serial.println(targetDistance);
delay(250);
}
void GetData(){
data=pulseIn(out,LOW); //here we wait until "out" go LOW, we start measuring the duration and stops when "out" is HIGH again
Serial.print(data); //it's a time duration measured, which is related to frequency as the sensor gives a frequency depending on the color
Serial.print(" , ");
delay(20);
}
This is my vPython code:
import serial #import serial library
from visual import * #import vPython library
MyScene=display(title='My Virtual World') #Create your scene and give it a title.
MyScene.width=800 #We can set the dimension of your visual box. 800X800 pixels works well on my screen
MyScene.height= 800
MyScene.autoscale=False #We want to set the range of the scene manually for better control. Turn autoscale off
MyScene.range = (12,12,12) #Set range of your scene to be 12 inches by 12 inches by 12 inches.
target=box(length=.1, width=10,height=5, pos=(-6,0,0)) #Create the object that will represent your target (which is a colored card for our project)
myBoxEnd=box(length=.1, width=10,height=5, pos=(-8.5,0,0)) #This object is the little square that is the back of the ultrasonic sensor
myTube2=cylinder(color=color.blue, pos=(-8.5,0,-2.5), radius=1.5,length=2.5 ) #One of the 'tubes' in the front of the ultrasonic sensor
myTube3=cylinder(color=color.blue, pos=(-8.5,0,2.5), radius=1.5,length=2.5 ) #Other tube
myBall=sphere(color=color.red, radius=.3)
sensorData= serial.Serial('com5',115200) # Create senorData object to read serial port data coming from arduino
while True: #This is a while loop that will loop forever, since True is always True.
rate(25) #We need to tell Vpython how fast to go through the loop. 25 times a second works pretty well
while(sensorData.inWaiting()==0): # Wait here untill there is data on the Serial Port
pass # Do nothing, just loop until data arrives
textline = sensorData.readline() # read the entire line of text
dataNums=textline.split(' , ') #Remember to split the line of text into an array at the commas
red=float(dataNums[0]) # Make variables for Red, Blue, Green. Remember
green=float(dataNums[1]) # the array was read as text, so must be converted
blue=float(dataNums[2]) # to numbers with float command
dist=float(dataNums[3]) # last number in the list is the distance
if (dist>=1.5 and dist<=2.25): #only change color or target if target is between 1.5 and 2.25 inches from sensor
target.color=(red/255., green/255., blue/255.) #This keeps color from flickering.
target.pos=vector(-6 + dist,0,0) #Adjust the position of the target object to match the distance of the real target from the real sensor
The distance works just fine but the color sensor doesn't do its job. All the pins are connected properly. Here is how the circuit looks:
I can't figure out what's wrong with the code.