Offline
Newbie
Karma: 0
Posts: 44
|
 |
« on: December 30, 2012, 01:48:45 am » |
Okay so I am working on this laser harp project right now. Essential there is a laser that shines on a photocell and when the laser light is blocked by a hand, a note will play on a virtual musical keyboard. I have it setup right now and it is working however I just need to tweak it so it will be more musical sounding. When the laser is blocked it will repeatability hit the key until my hand is removed from the laser. Is there a way to have it stay down until my hand is removed so that the notes will sound more fluid? Also note I am using AAC keys for this project. const int LaserC=3; const int CellC=A0; int chqC=0; void setup() { Serial.begin(9600); pinMode(LaserC,OUTPUT);
}
void loop() { digitalWrite(LaserC,HIGH); chqC= analogRead(CellC);
if (chqC<830){ //min value to trigger the photocell Serial.println("hold,A"); } } Thanks for the help!
|
|
|
|
|
Logged
|
|
|
|
|
SE USA
Offline
Faraday Member
Karma: 33
Posts: 3617
@ssh0le
|
 |
« Reply #1 on: December 30, 2012, 02:02:28 am » |
its the old new vs old ... psudo-code byte oldbutton;
read(button) if (button != oldbutton) { do stuff oldbutton = button }
|
|
|
|
|
Logged
|
http://arduino.cc/forum/index.php?action=unread;boards=2,3,4,5,67,6,7,8,9,10,11,66,12,13,15,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,86,87,89,1;ALL
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 44
|
 |
« Reply #2 on: December 30, 2012, 02:09:59 am » |
its the old new vs old ... psudo-code byte oldbutton;
read(button) if (button != oldbutton) { do stuff oldbutton = button } The problem is that the value is constantly changing. When the laser is on it the analogRead value hovers between 830-1000 depending on how much of the laser hits the photocell. Could I get that to work even if the values will be changing constantly? Please try and bear with me. I am new to programming as a whole.
|
|
|
|
« Last Edit: December 30, 2012, 02:11:49 am by FullyJosh »
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #3 on: December 30, 2012, 07:29:42 am » |
The problem is that the value is constantly changing. You need to define a threshold. Above that triggers an action. Below that, nothing happens. Then, the new vs. old is a matter of "on this pass, am I above the threshold but was not last time, or am I below the threshold, but was not last time".
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 44
|
 |
« Reply #4 on: December 30, 2012, 10:38:59 am » |
The problem is that the value is constantly changing. You need to define a threshold. Above that triggers an action. Below that, nothing happens. Then, the new vs. old is a matter of "on this pass, am I above the threshold but was not last time, or am I below the threshold, but was not last time". I apologize if I am totally missing where you guys are coming from but I tried doing this and now have it doing almost the exact same thing. const int LaserC=2; //laser pin const int CellC=A0; //photocell int thres=830; //min value when laser is on int chqC=0; void setup() { Serial.begin(9600); pinMode(LaserC,OUTPUT);
}
void loop() { digitalWrite(LaserC,HIGH); chqC= analogRead(CellC); if (chqC<thres){ Serial.print("a"); thres=chqC; } else if (chqC>thres) { }
} It is still pressing the "a" key repetitively and it's almost too quick for the keyboard to register. Is it possible I should approach this differently and use something other than aac keys or Serial.print for that matter? I'm essential building a glorified Arduino keyboard or game controller.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #5 on: December 30, 2012, 10:43:52 am » |
chqC= analogRead(CellC); if (chqC<thres){ Serial.print("a"); thres=chqC; } else if (chqC>thres) { }
Now, you have a threshold. What you don't have is any record of the previous reading's position relative to the threshold. Re-read what I said. You want to output a value if the previous reading was not above the threshold and the current one is. You MUST keep track of the previous reading.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 44
|
 |
« Reply #6 on: December 30, 2012, 11:08:53 pm » |
chqC= analogRead(CellC); if (chqC<thres){ Serial.print("a"); thres=chqC; } else if (chqC>thres) { }
Now, you have a threshold. What you don't have is any record of the previous reading's position relative to the threshold. Re-read what I said. You want to output a value if the previous reading was not above the threshold and the current one is. You MUST keep track of the previous reading. Okay so I have been trying to rationalize what you have been saying and I gave it a shot. I am totally missing the boat on something. I tried to explain what I was thinking. chqC= analogRead(CellC); if (chqC<thres){ store=HIGH; //store previous value as high if it is less than the threshold } else if (chqC>=thres) { store=LOW; //store previous value as low if it is greater than the threshold } if ((store=HIGH) && (chqC>=thres)){ //if the stored value is high and the current value is grater than the threshold then print "a" Serial.print("a"); } }{/code] Is this not working because the store value is getting overwritten before I was reading this article http://siliconrepublic.blogspot.ca/2010/08/this-summer-i-have-been-tinkering-with.htmlg-with.html and he was saying something along the lines of aac keys repetitively hitting the key and doesn't allow the user to physically hold down the key for periods of time. In my case that would be holding down a note. Is it possible I need to try approaching this problem differently?
|
|
|
|
« Last Edit: December 31, 2012, 12:25:36 am by FullyJosh »
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #7 on: December 31, 2012, 07:12:21 am » |
if ((store=HIGH) && (chqC>=thres)){ //if the stored value is high and the current value is grater than the threshold then print "a"
Assigning a value to HIGH in the if test is probably not what you want to be doing.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 44
|
 |
« Reply #8 on: December 31, 2012, 08:03:22 am » |
if ((store=HIGH) && (chqC>=thres)){ //if the stored value is high and the current value is grater than the threshold then print "a"
Assigning a value to HIGH in the if test is probably not what you want to be doing. I tried assigning other values. Neither seemed to do the trick. The high and low thing was just something I tried before posting when I was testing a bunch of possible solutions. Anything else you suggest I try?
|
|
|
|
« Last Edit: December 31, 2012, 08:15:19 am by FullyJosh »
|
Logged
|
|
|
|
|
Asnieres sur Seine - France
Offline
Jr. Member
Karma: 0
Posts: 53
|
 |
« Reply #9 on: December 31, 2012, 08:15:59 am » |
I'm new to Arduino but old to C programming... could this possibly just be the simple assignment rather than test? As you're already setting store to HIGH or LOW before the test... Rather than if ((store=HIGH) && (chqC>=thres)){
Shouldn't it be? if ((store==HIGH) && (chqC>=thres)) {
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 44
|
 |
« Reply #10 on: December 31, 2012, 08:29:06 am » |
I'm new to Arduino but old to C programming... could this possibly just be the simple assignment rather than test? As you're already setting store to HIGH or LOW before the test... Rather than if ((store=HIGH) && (chqC>=thres)){
Shouldn't it be? if ((store==HIGH) && (chqC>=thres)) {
I can't believe I made that mistake! Sadly it didn't fix the problem. I just tested it again now.
|
|
|
|
|
Logged
|
|
|
|
|
Milton Keynes UK
Offline
Tesla Member
Karma: 88
Posts: 6287
-
|
 |
« Reply #11 on: December 31, 2012, 08:46:45 am » |
I can't believe I made that mistake! Sadly it didn't fix the problem. I just tested it again now.
I think you have fixed that problem, but presumably it's not the only problem in your code. It's not at all unusual to have multiple bugs, and you will need to locate and fix each of them before everything works. To start with, now that you know you've made this mistake in one place, I suggest you carefully review the rest of your code for any other mistakes where you used an assignment instead of a condition, or vice versa.
|
|
|
|
|
Logged
|
|
|
|
|
Seattle, WA USA
Offline
Brattain Member
Karma: 311
Posts: 35470
Seattle, WA USA
|
 |
« Reply #12 on: December 31, 2012, 12:07:31 pm » |
Your code would be a lot easier to see the structure of if every { was on its own line, and you used Tppls + Auto Format to fix the horrid indenting. Do that, and fix the other mistakes that have been pointed out, and post your code again.
|
|
|
|
|
Logged
|
|
|
|
|
United Kingdom
Offline
Faraday Member
Karma: 130
Posts: 4643
|
 |
« Reply #13 on: December 31, 2012, 12:31:44 pm » |
Try this: const int threshold = 830; bool cellC_active = false;
void setup() { Serial.begin(9600); pinMode(LaserC,OUTPUT); digitalWrite(laserC, OUTPUT); }
void loop() { bool cellC_wasActive = cellC_active; // remember whether the cell was already active cellC_active = (analogRead(CellC) >= threshold); // update the active/inactive state if (cellC_active && !cellC_wasActive) // if the state has changed from inactive to active... { Serial.print("a"); //... then log to serial monitor } }
Then read about arrays to find out how to generalise it to multiple strings.
|
|
|
|
|
Logged
|
Formal verification of safety-critical software, software development, and electronic design and prototyping. http://www.eschertech.com
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 44
|
 |
« Reply #14 on: December 31, 2012, 07:05:13 pm » |
My current code is this const int LaserC=2; const int CellC=A0;
int thres=830; int chqC=0; int store=0;
void setup() { Serial.begin(9600);
pinMode(LaserC,OUTPUT);
}
void loop() {
digitalWrite(LaserC,HIGH);
chqC= analogRead(CellC);
if (chqC<thres) { store=HIGH; }
else if (chqC>=thres) { store=LOW; }
if ((store==HIGH) && (chqC>=thres)) { Serial.print("a"); } }
Try this: const int threshold = 830; bool cellC_active = false;
void setup() { Serial.begin(9600); pinMode(LaserC,OUTPUT); digitalWrite(laserC, OUTPUT); }
void loop() { bool cellC_wasActive = cellC_active; // remember whether the cell was already active cellC_active = (analogRead(CellC) >= threshold); // update the active/inactive state if (cellC_active && !cellC_wasActive) // if the state has changed from inactive to active... { Serial.print("a"); //... then log to serial monitor } }
Then read about arrays to find out how to generalise it to multiple strings. Your code works MUCH better than mine and works the way I want when in the serial monitor however it is still pressing the key too fast and doesn't press the note. Is there any way I could possibly tweek this to work a little bit better? Edit: Okay so I have been testing out the code dc42 posted and I am noticing that when I am in the serial monitor everything is working as needed, however when I run aac keys I notice that sometimes when I go to cover the laser, that the actual laser cuts out and will blink at random on it's own. I noticed the laser do this with other codes but I figured it might have had something to do with my code being 'wonky'.
|
|
|
|
« Last Edit: December 31, 2012, 07:18:42 pm by FullyJosh »
|
Logged
|
|
|
|
|
|