The task this week was fabricate sensors and program them.
Sensors:
A sensor is an electronic device that takes data from the real world and transforms them into electrical quantities.
In total we will fabricate 6 btw sensors, then we will appointing and detail the list of components for each one.
Light Sensor:
- 1 Microcontroller AtTiny45
- 1 capacitor 1UF
- 1 resistor of 10k Ω
- 1 phototransistor
- 1 resistor 49.9k Ω
- Headers
Manufacturing:
For manufacturing I used the Roland modeled MDX20, double-sided tape, isopropyl alcohol and a copper plate.
The following is weld the cards one by one, helping us of a welder, tin wire and paste for welding.
Then of weld, the result is the following:
Programming:
To schedule our sensors, we are going to take as example the light sensor.
What we do is to enter the page:
http://academy.cba.mit.edu/classes/input_devices/index.html
And we download the files .c and "make"
We connected the FabISP and the FTDI cable to the card as in the following image:
Then we opened the console of UBUNTU and we going to the folder where we have the files.
We write in the console:
sudo make -f hello.light.45.make program-usbtiny
We obtain:
Then we write:
avrdude -p t45 -c usbtiny -U flash:w:hello.light.45.c.hex
We obtain:
Finally we write:
sudo make -f hello.light.45.make program-usbtiny
We obtain:
To display the data obtained by the sensors, we downloaded the files .py and write in console:
python hello.light.45.py /dev/ttyUSB1
We obtain:
For the others sensors:
Observations:
In Ubuntu we have to have both installed Python Tkinter, Pyserial and Numpy.
Also check the connection port on the FTDI, in some cases is ttyUSB0.
After programming the sensors, the following was customize the codes. For this I used Python and smtplib library that allowed me to send mail messages to my email when the amount of light was high.
Code:
## hello.light.45.py## receive and display light level# hello.light.45.py serial_port## Neil Gershenfeld# CBA MIT 10/24/09## (c) Massachusetts Institute of Technology 2009# Permission granted for experimental and personal use;# license for commercial sale available from MIT## Modified by Michael Hurtado#fromTkinterimport*importtimeimportserialimportsmtplib
WINDOW =600# window size
eps =0.5# filter time constantfilter=0.0# filtered value
TO ='receptor@gmail.com'
GMAIL_USER ='emisor@gmail.com'
GMAIL_PASS ='pass'
SUBJECT ='Home Message'
TEXT ='The lights in garden are on'defsend_mail():
print("sending email")
smtpserver = smtplib.SMTP("smtp.gmail.com",587)
smtpserver.ehlo()
smtpserver.starttls()
smtpserver.ehlo
smtpserver.login(GMAIL_USER, GMAIL_PASS)
header ='To: '+ TO +'\n'+'From: '+ GMAIL_USER
header = header +'\n'+'Subject:'+ SUBJECT +'\n'print header
msg = header +'\n'+ TEXT +' \n\n'
smtpserver.sendmail(GMAIL_USER, TO, msg)
smtpserver.close()
defidle(parent,canvas):
globalfilter, eps
## idle routine#
byte2 =0
byte3 =0
byte4 =0
ser.flush()
while1:
## find framing #
byte1 = byte2
byte2 = byte3
byte3 = byte4
byte4 =ord(ser.read())
if ((byte1 ==1) & (byte2 ==2) & (byte3 ==3) & (byte4 ==4)):
break
low =ord(ser.read())
high =ord(ser.read())
value =256*high + low
filter= (1-eps)*filter+ eps*value
x =int(.2*WINDOW + (.9-.2)*WINDOW*filter/1024.0)
canvas.itemconfigure("text",text="%.1f"%filter)
canvas.coords('rect1',.2*WINDOW,.05*WINDOW,x,.2*WINDOW)
canvas.coords('rect2',x,.05*WINDOW,.9*WINDOW,.2*WINDOW)
canvas.update()
parent.after_idle(idle,parent,canvas)
#print(filter)if (filter<45):
send_mail()
filter=100## check command line arguments##if (len(sys.argv) != 2):# print "command line: hello.light.45.py serial_port"# sys.exit()#port = sys.argv[1]
port ='COM5'#for windows## open serial port#
ser = serial.Serial(port,9600)
ser.setDTR()
## set up GUI#
root = Tk()
root.title('hello.light.45.py (q to exit)')
root.bind('q','exit')
canvas = Canvas(root, width=WINDOW, height=.25*WINDOW, background='white')
canvas.create_text(.1*WINDOW,.125*WINDOW,text=".33",font=("Helvetica", 24),tags="text",fill="#0000b0")
canvas.create_rectangle(.2*WINDOW,.05*WINDOW,.3*WINDOW,.2*WINDOW, tags='rect1', fill='#b00000')
canvas.create_rectangle(.3*WINDOW,.05*WINDOW,.9*WINDOW,.2*WINDOW, tags='rect2', fill='#0000b0')
canvas.pack()
## start idle loop#
root.after(100,idle,root,canvas)
root.mainloop()
Then I used Processing and the library Soundcipher to generate sound and I used particles to generate a visual interactive in accordance with the variation of light.
Code:
importarb.soundcipher.*;importarb.soundcipher.constants.*;importprocessing.serial.*;
Serial myPort;// Create object from Serial classint val;// Data received from the serial portint sensorData;// Data recieved from the serial port with 1,2,3,4 framing numbers filtered outint highVal;//high value read in from Neil's C code int lowVal;//low value read in from Neil's C code int actualVal;// adjusted sensor valuefloat eps =0.5;float filter =0.0;int NUM_PARTICLES =200;float w=500,c;
ParticleSystem p;
SoundCipher sc =new SoundCipher(this);voidsetup(){
smooth();//size(displayWidth,displayHeight);
size(640,480);
background(0);
p =new ParticleSystem();
strokeWeight(4);
String portName = Serial.list()[0];
myPort =new Serial(this, portName,9600);}voiddraw(){if(myPort.available()>0){// If data is available
val = myPort.read();// read it and store it in valif(val >4){// Filter out the framing numbers: 1,2,3,4
highVal = myPort.read();// read the high value sent from sensor and store it
lowVal = myPort.read();// read low value from sensor it and store it
actualVal =256*(highVal + lowVal);// getting the actual value of the sensor
filter =(1-eps)*filter + eps*actualVal;
println("The actualVal is "+ filter);//print to the screen}
colorMode(HSB,w);//c=255*sin(mouseX*mouseY/255);int d=(int)filter;
c=map(d,0,1024,0,500);
sc.playNote((int)c/10,100,2.0);//println(frameCount);
noStroke();
fill(0,5);
rect(0,0,width,height);
p.update();
p.render();}}classParticle{
PVector position, velocity;
Particle(){
position =new PVector(random(width),random(height));
velocity =new PVector();}voidupdate(){
velocity.x=20*(noise(filter/10+position.y/100)-0.5);
velocity.y=20*(noise(filter/10+position.x/100)-0.5);
position.add(velocity);if(position.x<0)position.x+=width;if(position.x>width)position.x-=width;if(position.y<0)position.y+=height;if(position.y>height)position.y-=height;}voidrender(){
stroke(c,w,w);
line(position.x,position.y,position.x-velocity.x,position.y-velocity.y);}}classParticleSystem{
Particle[] particles;
ParticleSystem(){
particles =new Particle[NUM_PARTICLES];for(int i =0; i < NUM_PARTICLES; i++){
particles[i]=new Particle();}}voidupdate(){for(int i =0; i < NUM_PARTICLES; i++){
particles[i].update();}}voidrender(){for(int i =0; i < NUM_PARTICLES; i++){
particles[i].render();}}}