dilluns, 7 de juliol del 2014

8bit pseudo-theremin (4): afegir un led bicolor per indicar el tempo

A l'article anterior vaig afegir un potenciòmetre per indicar el tempo. El problema és que no hi havia cap indicador visual del tempo actual. Per aquest motiu he decidit afegir un led de dos colors per indicar-ho.

Esquema del circuit

El codi no canvia gaire, a nivell bàsic s'ha afegit un vector amb dos pins (led vermell, led verd) i es va activant o desactivant depenent del cicle on s'estigui.


/*
 Translate HC-SR04 Ping distance sensor into buzzer tone with a potentiometer tempo
 
 Author: Ferran Recio
 This code is part of the project 8bit pseudo-theremin (http://laveudet.blogspot.com.es/2014/07/pseudo-theremin-8bits-part-0.html)
 
 Code based on:
 
 HC-SR04 Ping distance code by ScottC here: http://arduinobasics.blogspot.com.au/2012/11/arduinobasics-hc-sr04-ultrasonic-sensor.html
 buzzer tutorial here:  http://arduino.cc/en/Tutorial/Tone
 
 on 04 Jul 2014.
 */

#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin
#define LEDPin 13 // Onboard LED
 
int potenPid = A1;

int buzzerPin = 10;
int buzztone = 0;

//buzzer tone range
int maxbuzztone = 2500;//4978;
int minbuzztone = 1;

int maximumRange = 30; // Maximum range needed
int minimumRange = 1; // Minimum range needed
long duration, distance; // Duration used to calculate distance

//marcador de tempo
int tempo[] = {2,3};//leds
int currled = 0;

int delayval = 25;


void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
  pinMode(buzzerPin, OUTPUT);   // sets the pin as output
  
  int i;
  for (i = 0; i < 2; i = i + 1) {
    pinMode(tempo[i], OUTPUT);
  }
  
}

void loop() {
  /* The following trigPin/echoPin cycle is used to determine the
   distance of the nearest object by bouncing soundwaves off of it. */ 
   digitalWrite(trigPin, LOW); 
   delayMicroseconds(2);
  
   digitalWrite(trigPin, HIGH);
   delayMicroseconds(10); 
   
   digitalWrite(trigPin, LOW);
   duration = pulseIn(echoPin, HIGH);
   
   //Calculate the distance (in cm) based on the speed of sound.
   distance = duration/58.2;
   
   if (distance >= maximumRange || distance <= minimumRange){
     //Serial.println("-1");
     digitalWrite(LEDPin, LOW);
     noTone(buzzerPin);
   }
   else {
     digitalWrite(LEDPin, HIGH);
     
     buzztone = map(distance, minimumRange, maximumRange, minbuzztone, maxbuzztone);
     buzztone = maxbuzztone - buzztone;
     
     tone(buzzerPin,buzztone);
   }
   
   //tempo
   if (currled==0) {
    currled = 1;
    digitalWrite(tempo[0], HIGH);
    digitalWrite(tempo[1], LOW);
   } else {
    currled = 0;
    digitalWrite(tempo[0], LOW);
    digitalWrite(tempo[1], HIGH);
   }

   
   //pillem el delay
   delayval = analogRead(potenPid);
   delay(delayval+1);
}

Aquest el vídeo de l'efecte:


divendres, 4 de juliol del 2014

8bit pseudo-theremin (3): afegir un potenciometre per marcar el tempo

El primer pas del 8bit Theremin convertia la distancia en notes del brunzidor. Tot i això, el so era força molest perquè arribava a notes molt agudes i perquè l'espera entre notes era de només 25 milisegons.

El següent pas és afegir un potenciòmetre per tal d'indicar l'espera entre tons. O sigui, el tempo.

Esquema del cablejat

En aquest cas, el codi recull el valor del potenciòmetre i el fa servir de cara a l'espera entre execucions de la funció loop. A més, s'han polit els distàncies i el rang de tons del brunzidor.


/*
 Translate HC-SR04 Ping distance sensor into buzzer tone with a potentiometer tempo
 
 Author: Ferran Recio
 This code is part of the project 8bit pseudo-theremin (http://laveudet.blogspot.com.es/2014/07/pseudo-theremin-8bits-part-0.html)
 
 Code based on:
 
 HC-SR04 Ping distance code by ScottC here: http://arduinobasics.blogspot.com.au/2012/11/arduinobasics-hc-sr04-ultrasonic-sensor.html
 buzzer tutorial here:  http://arduino.cc/en/Tutorial/Tone
 
 on 04 Jul 2014.
 */

#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin
#define LEDPin 13 // Onboard LED
 
int potenPid = A1;

int buzzerPin = 10;
int buzztone = 0;

//buzzer tone range
int maxbuzztone = 2500;//4978;
int minbuzztone = 1;

int maximumRange = 30; // Maximum range needed
int minimumRange = 1; // Minimum range needed
long duration, distance; // Duration used to calculate distance

int delayval = 25;


void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
  pinMode(buzzerPin, OUTPUT);   // sets the pin as output
  
}

void loop() {
  /* The following trigPin/echoPin cycle is used to determine the
   distance of the nearest object by bouncing soundwaves off of it. */ 
   digitalWrite(trigPin, LOW); 
   delayMicroseconds(2);
  
   digitalWrite(trigPin, HIGH);
   delayMicroseconds(10); 
   
   digitalWrite(trigPin, LOW);
   duration = pulseIn(echoPin, HIGH);
   
   //Calculate the distance (in cm) based on the speed of sound.
   distance = duration/58.2;
   
   if (distance >= maximumRange || distance <= minimumRange){
     digitalWrite(LEDPin, LOW);
     noTone(buzzerPin);
   }
   else {
     digitalWrite(LEDPin, HIGH);
     
     buzztone = map(distance, minimumRange, maximumRange, minbuzztone, maxbuzztone);
     buzztone = maxbuzztone - buzztone;
     
     tone(buzzerPin,buzztone);
   }

   
   //pillem el delay
   delayval = analogRead(potenPid);
   delay(delayval+1);
}

A continuació poso un vídeo de com funciona:


8bit Pseudo-Theremin (2): sensor d'ultrasons i buzzer

El primer pas per fer el meu pseudo-theremin de 8 bits consisteix en recollir el valor del sensor de distàncies d'ultrasons i convertir-lo en un to per al brunzidor. Per fer-ho només m'ha sigut necessari combinar els meus dos anteriors tutorials sobre aquests sensors.

Esquema de connexió

El codi no es especialment complicat d'entendre. La clau està en fer servir la funció map per fer una regla de tres entre la distancia i el to i després invertir-lo perquè sigui més agut com més aprop s'estigui del sensor.

/*
 Translate HC-SR04 Ping distance sensor into buzzer tone.
 
 Author: Ferran Recio
 This code is part of the project 8bit pseudo-theremin (http://laveudet.blogspot.com.es/2014/07/pseudo-theremin-8bits-part-0.html)
 
 Code based on:
 
 HC-SR04 Ping distance code by ScottC here: http://arduinobasics.blogspot.com.au/2012/11/arduinobasics-hc-sr04-ultrasonic-sensor.html
 buzzer tutorial here:  http://arduino.cc/en/Tutorial/Tone
 
 on 04 Jul 2014.
 */


#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin
#define LEDPin 13 // Onboard LED

int buzzer = 11;//buzzer pin

int buzztone = 0;

//buzzer tone range
int maxbuzztone = 4978;
int minbuzztone = 1;

//distance range
int maximumRange = 100; // Maximum range needed
int minimumRange = 0; // Minimum range needed
long duration, distance; // Duration used to calculate distance

void setup() {
 Serial.begin (9600);
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);
 pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
 
 pinMode(buzzer, OUTPUT);   // sets the pin as outpu
}

void loop() {
/* The following trigPin/echoPin cycle is used to determine the
 distance of the nearest object by bouncing soundwaves off of it. */ 
 digitalWrite(trigPin, LOW); 
 delayMicroseconds(2); 

 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10); 
 
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 
 //Calculate the distance (in cm) based on the speed of sound.
 distance = duration/58.2;
 
 if (distance >= maximumRange || distance <= minimumRange){
 /* Send a negative number to computer and Turn LED ON 
 to indicate "out of range" */
 Serial.println("-1");
 digitalWrite(LEDPin, HIGH);
 
 noTone(buzzer);
 }
 else {
 /* Send the distance to the computer using Serial protocol, and
 turn LED OFF to indicate successful reading. */
 //Serial.println(distance);
 digitalWrite(LEDPin, LOW); 
 
 buzztone = map(distance, minimumRange, maximumRange, minbuzztone, maxbuzztone);
 buzztone = maxbuzztone - buzztone;
 Serial.println(buzztone);
 tone(buzzer,buzztone);
 }
 
 //Delay 50ms before next reading.
 delay(25);
}

El so de moment es força horrible, però espero anar-ho polint. A continuació poso un vídeo del que fa (el vídeo és d'una versió anterior a invertir el to, pel que sona més greu com més aprop):

 Vídeo de com funciona

8bit Pseudo-Theremin (part 1)

Fa una parell de setmanes vaig tenir la sort d'assistir a la Mini Maker Fair Barcelona. Com ja va passar l'any passat, el principal atractiu seguien sent les impressores 3D (i no és per menys) però també hi havia molts altres projectes interessants i vaig sortir amb moltes idees.

Un d'aquest projectes va ser l'estand de Rockin' Tec Projects, on tenien un aparell anomenat RTP's etherial-arpeggiator. Aquest prototipus usava dos sensors d'ultrasons, arduino, i un programa de l'estil Pure Data, per fer quelcom que només pot ser descrit com un Theremin per a música electrònica. Per desgràcia l'únic vídeo que hi ha està a la pàgina de Facebook del projecte i no es pot fer embed.

Com a afegit, als pocs dies vaig trobar-me, a la pàgina Thingivers, amb un model 3D per imprimir que formava part d'un projecte anomenat VIA (Visual Impairment Aid). De nou, un arduino i un sensor de distància, aquest cop acompanyat d'un brunzidor.



Això ha fet que em piqui la curiositat i m'he proposat fer un pseudo-theremin de 8 bits. Si ve no crec que arribi tant lluny com els dos projectes anteriors ni que tingui cap utilitat real, sí que em servirà d'excusa per anar fent proves. Si tot va bé, durant els pròxims articles aniré explicant pas a pas el que vaig fent perquè serveixi a mode de tutorial.

dijous, 3 de juliol del 2014

Connectar un sensor de distància d'ultrasons a l'Arduino

Malgrat el nom que té, un detector de distància d'ultrasons es un dels components més clàssics d'Arduino, sobretot si estem interessats en la robòtica. Com el sou propi nom indica, aquest sensor detecta distàncies mitjançant ultrasons i permet, per exemple, detectar la distancia d'un mur o d'una mà. Com veurem, és un sensor força senzill d'usar i fàcil d'aconseguir.

Com és connecta

El sensor té 4 pins:
  • VCC: entrada de voltatge. Va directe a 5V de l'arduino
  • Trig: abreviació de "Trigger" (disparador en català), és el pin que es fa servir per indicar al sensor que emeti ultrasons. En aquest cas el connectarem al 7.
  • Echo: pin per rebre l'eco de l'ultrasò i calcular la distancia. En aquest cas el connectarem al 8.
  • GND: ground. Va directe a l'arduino
Esquema de la connexió (imatge feta amb Fritzing)

Com funciona

La principal dificultat d'aquest sensor es saber com funciona. Per sort hi ha gent mola eixerida que ho ha fet abans i ho documenta millor que aquest bloc (concretament el bloc de Arduino Basics). L'algorisme a grans trets és el següent:
  1. Posem el LOW el pin Trigger per garantis que no estiguéssim emeten
  2. Esperem una estona prudencial per evitar ultrasons residuals (2 microsegons)
  3. Posem el trigger a HIGH per emetre ultrasons
  4. Esperem una estona per permetre el rebot (10 microsegons)
  5. Posem de nou el trigger a LOW per deixar d'emetre
  6. agafem el resultat del pin Echo amb la funció pulseIn
  7. Calculem la distància dividint per la velocitat del so (en serio). Això sona molt difícil però realment es dividir el resultat del pas anterior per 58.2
Codi d'exemple

El següent exemple està directament agafat de la web de Arduino Basics. Concretament, llegeix la distància cada 50 milisegons i escriu el resultat al port serie.


/*
 HC-SR04 Ping distance sensor:
 VCC to arduino 5v 
 GND to arduino GND
 Echo to Arduino pin 7 
 Trig to Arduino pin 8
 
 This sketch originates from Virtualmix: http://goo.gl/kJ8Gl
 Has been modified by Winkle ink here: http://winkleink.blogspot.com.au/2012/05/arduino-hc-sr04-ultrasonic-distance.html
 And modified further by ScottChere: http://arduinobasics.blogspot.com.au/2012/11/arduinobasics-hc-sr04-ultrasonic-sensor.html
 on 10 Nov 2012.
 */


#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin
#define LEDPin 13 // Onboard LED

int maximumRange = 200; // Maximum range needed
int minimumRange = 0; // Minimum range needed
long duration, distance; // Duration used to calculate distance

void setup() {
 Serial.begin (9600);
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);
 pinMode(LEDPin, OUTPUT); // Use LED indicator (if required)
}

void loop() {
/* The following trigPin/echoPin cycle is used to determine the
 distance of the nearest object by bouncing soundwaves off of it. */ 
 digitalWrite(trigPin, LOW); 
 delayMicroseconds(2); 

 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10); 
 
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 
 //Calculate the distance (in cm) based on the speed of sound.
 distance = duration/58.2;
 
 if (distance >= maximumRange || distance <= minimumRange){
 /* Send a negative number to computer and Turn LED ON 
 to indicate "out of range" */
 Serial.println("-1");
 digitalWrite(LEDPin, HIGH); 
 }
 else {
 /* Send the distance to the computer using Serial protocol, and
 turn LED OFF to indicate successful reading. */
 Serial.println(distance);
 digitalWrite(LEDPin, LOW); 
 }
 
 //Delay 50ms before next reading.
 delay(50);
}
 
NOTA: el codi font ha sigut formatejat amb hilite.me