Hi
I have a project to create a very simple theremin, with the notes activated by an ultrasonic sensor HC-SR04, and a potentiometer for the volume. In parallel, I would like to have a chase led thanks to a shift register 74HC595. I am using an Arduino Uno. I started from the following codes:
-for the theremin:
const int trigger = 19;
const int echo = 18;
const int piezo = 5;
int distance = 0;
int distanceHigh = 0;
int lengthOfScale = 0;
int note = 0;
//A Minor pentatonic scale
int scale[] = {
147, 165, 196, 220, 262, 294, 330, 392, 440,
523, 587, 659, 784, 880, 1047, 1175, 1319, 1568,
1760, 2093, 2349
};
//C Major scale
//int scale[] = {
// 131, 147, 165, 175, 196, 220, 247, 262, 294,
// 330, 349, 392, 440, 494, 523, 587, 659, 698,
// 784, 880, 988, 1047
//};
void setup() {
pinMode(trigger, OUTPUT);
pinMode(echo, INPUT);
while (millis() < 5000) {
digitalWrite(trigger, HIGH);
digitalWrite(trigger, LOW);
distance = pulseIn(echo, HIGH);
if (distance > distanceHigh) {
distanceHigh = distance;
}
}
for (byte i = 0; i < (sizeof(scale) / sizeof(scale[0])); i++) {
lengthOfScale += 1;
}
}
void loop() {
digitalWrite(trigger, HIGH);
digitalWrite(trigger, LOW);
distance = pulseIn(echo, HIGH);
note = map(distance, 250, distanceHigh, scale[0], scale[lengthOfScale - 1]);
for (byte j = 0; j < (lengthOfScale); j++) {
if (note == scale[j]) {
tone(piezo, note);
break;
}
else if (note > scale[j] && note < scale[j + 1]) {
note = scale[j];
tone(piezo, note);
break;
}
}
delay(30);
}
-For the led chase:
//constantes pour les broches de commande du 74HC595
int latchPin = 7;
int clockPin = 8;
int dataPin = 6;
int outputEnablePin = 3;
byte leds = 0;
void setup()
{
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(outputEnablePin, OUTPUT);
}
void loop()
{
setBrightness(255);
leds = 0;
updateShiftRegister();
delay(10);
for (int i = 0; i < 8; i++)
{
bitSet(leds, i);
updateShiftRegister();
delay(50);
}
for (byte b = 255; b > 0; b--)
{
setBrightness(b);
delay(10);
}
}
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}
void setBrightness(byte brightness) // 0 to 255
{
analogWrite(outputEnablePin, 255-brightness);
}
I mixed the two codes, I created this, which compiles:
const int trigger = 19;//pin du hcsr04 pour déclencher piezzo en fonction de la distance
const int echo = 18;//idem
const int piezo = 5;
int distance = 0;
int distanceHigh = 0;
int lengthOfScale = 0;
int note = 0;
//A Minor pentatonic scale
int scale[] = {
147, 165, 196, 220, 262, 294, 330, 392, 440,
523, 587, 659, 784, 880, 1047, 1175, 1319, 1568,
1760, 2093, 2349
};
//C Major scale
//int scale[] = {
// 131, 147, 165, 175, 196, 220, 247, 262, 294,
// 330, 349, 392, 440, 494, 523, 587, 659, 698,
// 784, 880, 988, 1047
//};
void setBrightness(byte brightness);
//constantes pour les broches de commande du 74HC595, chenillard de 8 leds
int latchPin = 7;
int clockPin = 8;
int dataPin = 6;
int outputEnablePin = 3;
byte leds = 0;
// Declaration des fonctions
void commande_piezzo();
void commande_led();
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(outputEnablePin, OUTPUT);
pinMode(trigger, OUTPUT);
pinMode(echo, INPUT);
while (millis() < 5000) {
digitalWrite(trigger, HIGH);
digitalWrite(trigger, LOW);
distance = pulseIn(echo, HIGH);
if (distance > distanceHigh) {
distanceHigh = distance;
}
}
for (byte i = 0; i < (sizeof(scale) / sizeof(scale[0])); i++) {
lengthOfScale += 1;
}
}
void loop() {
// Programme principal
commande_piezzo();
commande_led();
}
void commande_piezzo() {
digitalWrite(trigger, HIGH);
digitalWrite(trigger, LOW);
distance = pulseIn(echo, HIGH);
note = map(distance, 250, distanceHigh, scale[0], scale[lengthOfScale - 1]);
for (byte j = 0; j < (lengthOfScale); j++) {
if (note == scale[j]) {
tone(piezo, note);
break;
}
else if (note > scale[j] && note < scale[j + 1]) {
note = scale[j];
tone(piezo, note);
break;
}
delay(30);
}
}
void commande_led() {
setBrightness(255);
leds = 0;
updateShiftRegister();
delay(10);
for (int i = 0; i < 8; i++)
{
bitSet(leds, i);
updateShiftRegister();
delay(50);
}
for (byte b = 255; b > 0; b--)
{
setBrightness(b);
delay(10);
}
}
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}
void setBrightness(byte brightness) // 0 to 255
{
analogWrite(outputEnablePin, 255 - brightness);
}
and I noticed several problems:
-that the notes only changed after a complete revolution of the led chase, and not instantly as in the initial code of the Theremin;
-and in the following simulation on Tinkercad:
The 74HC595 chip received too much amperage: 90.6ma instead of 50ma
After researching, I found that the problem was with the delay, which interrupts the program, and the inherent inability of the arduino to perform simultaneous tasks.
My question is: should i better schedule with the millis () function, Or create classes like in this tutorial:
Since my project is very basic, what would be the easiest solution to have the attention of the arduino focused only on the notes, and a kind of infinite loop without modification for the leds ... Thank you for your advices.