Hello! I'm new to the forum, Arduino, and C programming in general, but I bought some books, and am starting to get the hang of things. My question is: I have 3 light sensors mounted in a half-circle, and a motor is connected to rotate the sensor array such that the center sensor remains facing the brightest light. The sketch I'm working on will read the 3 sensors, compare the right and left to the center, and direct the motor to rotate to bring the center sensor back to the brightest direction. I also want there to be a time-out, so that after a given time, say around 30 seconds, if the motor hasn't achieved the proper movement, the program lights a trouble LED and hangs, without rattling relays or setting fires. I hope I have been clear. I have tried if statements, if, else statements, while, and do, while, but nothing seems to work properly. I have not tried the switch case statement yet, as the format is a bit tricky (for me, anyway). Any thoughts, advice or insight is appreciated. I'm not looking for spoon-feeding, just a swift boot in the right direction, LOL. The sketch I have so far is pretty long, but I will post relevant parts if that would help. Thanks!
Have you checked the inputs from the light sensors to be sure you're getting sensible results?
Use the analogRead function to get the values, and observe the values using Serial.write and the IDE's serial monitor whlle turning the unit by hand.....
Allan, thanks for the reply. I wrote a simple sketch that does just that. The sensors behave exactly as I want. I came the closest with a fairly long if, else statement:
It is a clumsy attempt, but this is the stage I am at in the learning curve right now. I know there is an elegant solution, but it continues to elude me.
Allan, I quite agree that switch case seems to be the best bet, trouble is, my books don't cover that. I'll figure it out eventually. What would you recommend as the switch variable? That is where I always choke. The cases are easy, as they just set pins high/low to engage/disengage relays and LEDs. It's setting up the first part that kicks my butt.
When a program is suitably designed it makes development and troubleshooting much easier. By putting code into a series of single-purpose functions it is possible to test each part separately.
In general the use of the delay() function is inappropriate except for a quick-and-dirty test. See how millis() is used to manage timing without blocking in the tutorial code.
a thought on the sensors. what it seems you really want to do is to balance the left and right to be equal.
all the center does is to verify that the light is between the outboard sensors.
since there is no way to tell the center if it is on the brightest light without it sweeping back and forth, stability comes from the outboard sensors being equal.
this is the heart of solar panel tracking.
difference = up - down
if( difference <= 10)
if ( difference >= -10)
do nothing as you are close
Thank you all for the replies. They have all been very helpful. Sometimes the only thing needed is a fresh pair of eyes. I am in the process of reading Robin's excellent tutorial.
Dave...Duh! Thanks! That is exactly what I am trying to do, but was so blinded by the trees, I didn't see the forest. Thanks a ton!
I'm going back and starting over. It's good practice anyway. These things are amazing.
Well, thanks to the tips I got here, I got the detection part to work perfectly. I only need 3 sensors now to correct both azimuth and tilt, although I haven't actually done that yet; still using 4.
Now, onto the next item, actually switching the relays to control the motors is giving me fits, LOL It should be pretty simple: When a correction is indicated, call one of 4 functions to rotate CW, CCW, tilt up & tilt down, and keep the relay on until the values equalize. I've tried a few things, and get close, but no cigar.
I thought I understood that once a function was called, it stayed in the function until it was satisfied and exited the call, then went back to loop. But it now calls occasionally for both directions at once. Obviously, I am missing something...somethings.
I see now that programming is a lot like chess, a few minutes to learn the pieces and their moves, a lifetime to learn the game. It is fun, though.
Allan, I think I may have done a poor job of communicating what I have tried; the reason I added the detection in the move function was to know when to stop the motor. That does not work, as you surmised. I'll post the loop code that calls the move functions, as I should have done in the first place.
I guess what I was trying so poorly to communicate is: what is a good way to stop the motors when the desired position is achieved? I do plan to simplify this cumbersome loop down to 3 sensors, but the motor thing is what I am focused on now. I added serial.print commands to check the calls from the loop, and it worked perfectly, as near as I could tell, BTW.
Also, thanks a lot for your replies and patience. I always thought of myself as reasonably clever, but this stuff is either harder than it looks, or I am not as clever as I thought, LOL.
Geez, please disregard my last two posts. I think I figured it out: You have to actually TELL the thing when to shut off the relay. Duh! There is no need for a redundant detection line in the move call. Thanks Allan. Now I have to figure out how to throw a time-out feature for when the motor doesn't actually move. But before that, I need to do some more reading on the millis() command.
Just about got it. I just have to finish the compass routine, and add a motor time-out, and I'll be ready to test it on the real deal. Currently, I have a breadboard set up with the diagnostic and status LEDs, and input switches to test as I go.
Many thanks to Allan, Dave, and Robin for your help and advice. I have a clean (to me) sketch, with well defined functions. The loop part only has about 46 lines, some of which are comments, everything else is handled by ISRs and defined functions. The sketch in total has 487 lines so far, and the only part not hand written is the routine to convert the compass' raw data to a heading. (I don't remember trigonometric functions as well as I ought..)
It's been a real learning experience, for sure. Robin's "rules of order" really help to keep things organized. I'd post the results of my labors, but I'm afraid someone who actually knows what they are doing would be offended that I used 500 lines when they could have done the same thing with 20 lines, LOL. I still haven't worked with strings and arrays, and the compass library had some signs and commands I didn't recognize, either.
Arduinos being relatively simple things, I cannot imagine how folks write programs for modern, multi-core and multi-threaded systems. How do they keep all this stuff straight in their heads?
Computers work for people, not the other way around. If it is easier for you to write and maintain 500 lines then the 1-line wonder is counterproductive. The difficult part is the maintenance. Understanding what you wrote a few weeks ago can be surprisingly difficult.
To make a big system work, you just apply the same principles you just learned. Keep everything in small modules that have defined functions. Just moving the mouse pointer on the screen is a difficult program to write but once it's done, everyone can use that module.