scuola invernale di fisica 2012
TRANSCRIPT
Scuola invernale di Fisica 2012
Scuola Estiva Genova AIF-DIFI
Piano Lauree Scientifiche, modulo di formazione insegnanti in laboratorio
Daniele Grosso(1)
1. Dipartimento di Fisica (Università di Genova)
Una libreria di esempi
ARDUINO
Rilevare lo stato di un interruttore
ARDUINO
Rilevare lo stato di un interruttore const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
}
void loop(){
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(ledPin, HIGH);
}
else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
}
ARDUINO
Rilevare lo stato di un interruttore void setup() {
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
}
void loop() {
// read the state of the switch into a local variable:
int reading = digitalRead(buttonPin);
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonState = reading;
}
// set the LED using the state of the button:
digitalWrite(ledPin, buttonState);
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastButtonState = reading;
}
Bounce problem? Software debounce!
ARDUINO
Controllare un led
int ledPin = 13; // LED connected to digital pin 13
void setup()
{
pinMode(ledPin, OUTPUT); // sets the digital pin as output
}
void loop()
{
digitalWrite(ledPin, HIGH); // sets the LED on
delay(1000); // waits for a second
digitalWrite(ledPin, LOW); // sets the LED off
delay(1000); // waits for a second
}
Viene fatto lampeggiare un LED
Utilizziamo il pin 13 perche’ ha una resistenza di pull up in serie
(per questo è sufficiente un LED ed un programma)
Con opportune resistenze è possibile
pilotare più LED con un programma
ad es con piu’ DigitalWrite(…)
ARDUINO
Controllare un led RGB
int sensorPin = 3;
int bluePin = 5;
int blue1Pin = 10;
int greenPin = 6;
int redPin = 11;
int sensorValue = 0;
void setup (){
pinMode (redPin, OUTPUT);
pinMode (blue1Pin, OUTPUT);
pinMode (greenPin, OUTPUT);
pinMode (bluePin, OUTPUT);
Serial.begin (9600);
}
void loop (){
sensorValue = analogRead (sensorPin);
int ledFadeValue = map(sensorValue,0, 1023, 0, 255);
int ledFadeValue2 = map(sensorValue,0, 1023, 0, 255 );
int ledFadeValue3 = map(sensorValue,0, 1023, 255, 0);
int ledFadeValue4 = map(sensorValue,0, 1023, 255, 0);
analogWrite (11, ledFadeValue);
analogWrite (10, ledFadeValue2);
analogWrite (6, ledFadeValue3);
analogWrite (5, ledFadeValue4);
delay (20);
}
This Red, Green, Blue (RGB) 5mm LED has four
pins, one for each color and one for the common
Cathode. The Cathode is the longest pin. Use this one
LED for three status indicators or pulse width
modulate all three colors to mix any color you like.
Note: Pins 3 and 4 are switched in the datasheet, in
actuality pin 3 is blue, and pin 4 is green.
ARDUINO
Rilevare una resistenza variabile Il circuito è molto semplice:
un potenziometro collegato come segue:
PIN1 → 5V
PIN2 → ANALOG0
PIN3 → Ground int potPin = 2; // select the input pin for the potentiometer
int ledPin = 13; // select the pin for the LED
int val = 0; // variable to store the value coming from the
sensor
void setup() {
pinMode(ledPin, OUTPUT); // declare the ledPin as an
OUTPUT
}
void loop() {
val = analogRead(potPin); // read the value from the sensor
digitalWrite(ledPin, HIGH); // turn the ledPin on
delay(val); // stop the program for some time
digitalWrite(ledPin, LOW); // turn the ledPin off
delay(val); // stop the program for some time
}
ARDUINO
Rilevare una misura di luminosità
220ohm 10Kohm
int sensorMin = 1023; // minimum
sensor value
int sensorMax = 0; // maximum
sensor value
// calibrate during the first five seconds
while (millis() < 5000) {
sensorValue = analogRead(sensorPin);
// record the maximum sensor value
if (sensorValue > sensorMax) {
sensorMax = sensorValue;
}
// record the minimum sensor value
if (sensorValue < sensorMin) {
sensorMin = sensorValue;
}
}
È possibile usare la funzione map per la calibrazione:
sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);
ARDUINO
Rilevare una misura di pressione
FSR = Force Sensitive Resistor
ARDUINO
Controllo di un LED mediante FSR e PWM int fsrAnalogPin = 0; // FSR is connected to analog 0
int LEDpin = 11; // connect Red LED to pin 11 (PWM pin)
int fsrReading; // the analog reading from the FSR resistor
divider
int LEDbrightness;
void setup(void) {
Serial.begin(9600); // We'll send debugging information via the
Serial monitor
pinMode(LEDpin, OUTPUT);
}
void loop(void) {
fsrReading = analogRead(fsrAnalogPin);
Serial.print("Analog reading = ");
Serial.println(fsrReading);
// we'll need to change the range from the analog reading (0-
1023) down to the range
// used by analogWrite (0-255) with map!
LEDbrightness = map(fsrReading, 0, 1023, 0, 255);
// LED gets brighter the harder you press
analogWrite(LEDpin, LEDbrightness);
delay(100);
}
ARDUINO
Misura di flessione
Flex sensor The Flex sensor changes resistance between 10k Ohms (straight) and 40k Ohms (bent) (datasheet). We'll build a voltage divider circuit with a 22k resistor (red-red-orange-gold):
resistance increases
from ~900 Ohm straight
to ~22000 Ohm at 180 degrees
int CdS_PIN = 0; // select the input pin for the CdS Cell
int ledPIN = 13; // select the output pin for the LED
int CdS_VAL = 0; // variable to store the value coming from the CdS Cell
void setup() {
Serial.begin(9600); // set the baud rate for the serial window
pinMode(ledPIN, OUTPUT); // declare the ledPin as an OUTPUT
// ANALOG IN is an input by default
}
void loop() {
CdS_VAL = analogRead(CdS_PIN); // read the value from the CdS Cell
CdS_VAL = (CdS_VAL/2 + 16); // shift the CdS_VAL to be a useful flashrate
// (barely visible to 511ms)
digitalWrite(ledPIN, HIGH); // set the ledPIN HIGH, which turns on the LED
delay(CdS_VAL); // do nothing for (CdS_VAL) milliseconds
digitalWrite(ledPIN, LOW); // set the ledPIN LOW, which turns off the LED
delay(CdS_VAL); // do nothing for (CdS_VAL) milliseconds
Serial.println(CdS_VAL); // print CdS_VAL in the serial arduino serial window
}
ARDUINO
Misurare la temperatura con resistenze NTC int sensor=0; //analog pin
float temp;
float adc; //value of analog pin
float adcVolts; //value of analog pin in volts
//thermistor parameter
float beta=3950.0; //beta
float r0=4700.0; //resistance at t0 temperature
float t0=25.0 + 273.15; //Kelvin
float r1=10000.0;
float r2=4400.0;
float r; //r1 parallel r2
float rT; //resistance of thermistor
float k; //constant part of exponential equation
float vs; //effettive bias voltage
void setup(){
Serial.begin(9600);
r=( r1 * r2 ) / (r1 + r2); //r1 parallel r2
k = r0 * exp(-beta / t0); //constant part of exponential equation
vs= (r1 * 5.0) / (r1 + r2); //effective bias voltage
}
void loop(){
adc=analogRead(sensor);
adcVolts = adc * 5.0 / 1023; // convert the 10 bit ADC value to a
voltage
rT = adcVolts / ((vs – adcVolts)/r); // resistance of thermistor
temp = beta / log(rT / k) -273.15; //Celsius
Serial.print(temp,DEC);
Serial.println(”°C”);
}
I termistori non hanno una risposta lineare:
R=R0*e^{B/T-B/T0}
R0 (4.7K) è la resistenza ad una
temperatura nota T0, in Kelvin.
B (beta) è un parametro del termistore che
può essere calcolato a partire da una misura
oppure trovato nei datasheet
Quando conviene utilizzare un sensore di
temperatura come LM35
•Resistance at 25C
ARDUINO
Misurare la temperatura con LM35
lm35 fornisce 10 mV per ogni grado centigrado => la massima precisione è di mezzo grado centigrado
l'lm35 ha un range di misurazione da 0 a 100C
Per un range maggiore conviene (-40 a 150C)
ARDUINO
Misurazione temperatura con TMP36 //TMP36 Pin Variables
int sensorPin = 0; //the analog pin the TMP36's Vout (sense) pin is connected to
//the resolution is 10 mV / degree centigrade with a
//500 mV offset to allow for negative temperatures
/*
* setup() - this function runs once when you turn your Arduino on
* We initialize the serial connection with the computer
*/
void setup()
{
Serial.begin(9600); //Start the serial connection with the computer
//to view the result open the serial monitor
}
void loop() // run over and over again
{
//getting the voltage reading from the temperature sensor
int reading = analogRead(sensorPin);
// converting that reading to voltage, for 3.3v arduino use 3.3
float voltage = reading * 5.0 / 1024;
// print out the voltage
Serial.print(voltage); Serial.println(" volts");
// now print out the temperature
float temperatureC = (voltage - 0.5) * 100 ; //converting from 10 mv per degree wit 500
mV offset
//to degrees ((volatge - 500mV) times 100)
Serial.print(temperatureC); Serial.println(" degress C");
// now convert to Fahrenheight
float temperatureF = (temperatureC * 9 / 5) + 32;
Serial.print(temperatureF); Serial.println(" degress F");
delay(1000); //waiting a second
}
Price: $2.00 at the Adafruit shop
Temperature range: -40°C to 150°C / -
40°F to 302°F
Output range: 0.1V (-40°C) to 2.0V
(150°C) but accuracy decreases after 125°C
Power supply: 2.7V to 5.5V only, 0.05
mA current draw
ARDUINO
Controllare un buzzer void setup()
{
pinMode(11, OUTPUT); // pin as output
}
void loop()
{
analogWrite(11,128);
delay(500);
digitalWrite(11, LOW);
delay(500);
}
The sketch above will beep the piezo on and off,
and be somewhat annoying. Perfect.
However with the analogWrite(); function it is
impossible to use the full frequency range of the
piezo buzzer.
With a value of 254 for the duty cycle, the
frequency generated is around 1500 Hz:
ARDUINO
Knok sensor const int ledPin = 13; // led connected to digital pin 13
const int knockSensor = A0; // the piezo is connected to analog pin 0
const int threshold = 100; // threshold value to decide when the detected
sound is a knock or not
// these variables will change:
int sensorReading = 0; // variable to store the value read from the sensor
pin
int ledState = LOW; // variable used to store the last LED status, to
toggle the light
void setup() {
pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
Serial.begin(9600); // use the serial port
}
void loop() {
// read the sensor and store it in the variable sensorReading:
sensorReading = analogRead(knockSensor);
// if the sensor reading is greater than the threshold:
if (sensorReading >= threshold) {
// toggle the status of the ledPin:
ledState = !ledState;
// update the LED pin itself:
digitalWrite(ledPin, ledState);
// send the string "Knock!" back to the computer, followed by newline
Serial.println("Knock!");
}
delay(100); // delay to avoid overloading the serial port buffer
}
1Mohm resistor
Piezo buzzer
ARDUINO
Carica di un condensatore
http://www.nicolaamatucci.com/blog/2009/08/12/arduino-
esperimento-calcolo-del-tempo-di-scarica-di-un-condensatore/
ARDUINO
Controllo di un servomotore (pulse)
Un servomotore (o servo) è un motore che può essere mosso di un angolo variabile tramite un solo segnale di controllo.
int servoPin = 2; // Control pin for servo motor
int minPulse = 500; // Minimum servo position
int maxPulse = 2500; // Maximum servo position
int pulse = 0; // Amount to pulse the servo
long lastPulse = 0; // the time in milliseconds of the last pulse
int refreshTime = 20; // the time needed in between pulses
int analogValue = 0; // the value returned from the analog sensor
int analogPin = 0; // the analog pin that the sensor's on
void setup() {
pinMode(servoPin, OUTPUT); // Set servo pin as an output pin
pulse = minPulse; // Set the motor position value to the minimum
Serial.begin(9600);
}
void loop() {
analogValue = analogRead(analogPin); // read the analog input
pulse = map(analogValue,0,1023,minPulse,maxPulse); // convert the analog value
// to a range between minPulse
// and maxPulse.
// pulse the servo again if rhe refresh time (20 ms) have passed:
if (millis() - lastPulse >= refreshTime) {
digitalWrite(servoPin, HIGH); // Turn the motor on
delayMicroseconds(pulse); // Length of the pulse sets the motor position
digitalWrite(servoPin, LOW); // Turn the motor off
lastPulse = millis(); // save the time of the last pulse
}
}
ARDUINO
Controllo di un servomotore (servo.h)
#include <Servo.h> // include the servo library
Servo servoMotor; // creates an instance of the servo object to control a
servo
int analogPin = 0; // the analog pin that the sensor is on
int analogValue = 0; // the value returned from the analog sensor
int servoPin = 2; // Control pin for servo motor. As of Arduino 0017, can
be any pin
void setup() {
servoMotor.attach(servoPin); // attaches the servo on pin 2 to the servo
object
}
void loop()
{
analogValue = analogRead(analogPin); // read the analog input
(value between 0 and 1023)
analogValue = map(analogValue, 0, 1023, 0, 179); // map the analog value
(0 - 1023) to the angle of the servo (0 - 179)
servoMotor.write(analogValue); // write the new mapped
analog value to set the position of the servo
delay(15); // waits for the servo to get there
}
CARDUINO
Controllo di un carico (lampada)
const int transistorPin = 9;
// connected to the base of the transistor
void setup() {
// set the transistor pin as output:
pinMode(transistorPin, OUTPUT);
}
void loop() {
digitalWrite(transistorPin, HIGH);
delay(1000);
digitalWrite(transistorPin, LOW);
delay(1000);
}
Note: you can also use an IRF510 or IRF520 MOSFET transistor for this. They have the same pin configuration as
the TIP120, and perform similarly. They can handle more amperage and voltage, but are more sensitive to static
electricity damage
ARDUINO
Controllo di un carico (motore)
const int potPin = 0; // Analog in 0 connected to the potentiometer
const int transistorPin = 9; // connected to the base of the transistor
int potValue = 0; // value returned from the potentiometer
void setup() {
// set the transistor pin as output:
pinMode(transistorPin, OUTPUT);
}
void loop() {
// read the potentiometer, convert it to 0 - 255:
potValue = analogRead(potPin) / 4;
// use that to control the transistor:
analogWrite(9, potValue);
}
Note: you can also use an IRF510 or IRF520 MOSFET transistor for this. They have the same pin configuration as
the TIP120, and perform similarly. They can handle more amperage and voltage, but are more sensitive to static
electricity damage
ARDUINO
Controllare un relè
Conclusioni
Schede come l’ARDUINO
consentono di acquisire segnali analogici e digitali
consentono di controllare attuatori
sono basati su software e progetti open source
sono utilizzabili in ambiente windows, linux e MAC
hanno un costo contenuto
Queste caratteristiche ne fanno uno strumento utilizzabile in
laboratorio per esperienze di Fisica, Elettronica …