Go Down

Topic: A new spin on an old question in LED control... (Read 429 times) previous topic - next topic

mlynn

Oh! I see now what you did there with the button state... Changing from direct Boolean logic as it relates to the switch signal, to a logical variable that switches and maintains the state even after the button is released.

The addition of the "switchWasPressed" variable was the important little change that I had overlooked.

Goodness, so it was my unwillingness to be rigorous with the state machine that caused the problem.

Lesson learned, don't skimp on the details of state maintenance!


Problem solved. Thanks to all of you for the help, and expert advice.

For anyone finding this thread in the future, managing state is very important to achieving the control you desire.

To control the state of the LED with a single button press, required the implementation of a boolean variable to keep track of the previous state of the button, instead of directly encoding the HIGH or LOW signal into the state machine logic. Examining my first section of code will demonstrate what that later setup looks like. To achieve my desired outcome, of single press activation for an arbitrary and preset time period at a preset power, the "switchWasPressed" variable was required to keep track of the past state of the button so regardless of how long it was pressed, the LED was activated for precisely the specified interval.







larryd

#16
Nov 15, 2018, 12:53 am Last Edit: Nov 15, 2018, 05:34 pm by larryd
You had a programming problem, and a switch wiring hardware problem.

Switch change detection, is an important thing to master.
Also, proper timing of events is a must have skill.
'Fags' are very useful in programs too.
The 'type' you use for your varaiables can save your SRAM.

Although your switch now works with the changes suggested, you would be urged to wire your switch as examples S3 or S2 in the image below.

S3 is arguably better as you don't need an external resistor.
You would have to use INPUT_PULLUP in setup() as shown in the code at the top of the image.
A push gives a LOW (the inverse of what you have now).



In the future, a proper schematic (not Fritzing) and a good image of your wiring should accompany your question.

You can reduce your code size, but we'll leave that up to you.

Good luck with your projects!

EDIT:
Remember in some applications, you should also incorporate switch debounce code.





No technical PMs.
The last thing you did is where you should start looking.

mlynn

#17
Nov 15, 2018, 01:52 am Last Edit: Nov 15, 2018, 02:12 am by mlynn
Ah! A useful wiring diagram! I will take note of changes for the immediate future. I intend to make this a long term setup, and to add it to documentation for future users.  Thanks so much!

There is actually just one more thing that bothers me.

In the current implementation of the code and wiring, I find that the analogOutputValue is limited to 63, I need the full range of intensities for my particular application.

What happens, is, when I turn the potentiometer, the sensor value rises as the pot turns, all the way to 255, then returns to 0, and the outputvalue rises to 67 and then returns to 0 at the same time as the sensor value returns to zero. This continues until the potentiometer is at it's maximum rotation.

Any sage advice here? is there some interaction of the boolean logic and the way I do my mapping that causes the change?





larryd

#18
Nov 15, 2018, 02:05 am Last Edit: Nov 15, 2018, 02:27 am by larryd
Quote
In the current implementation of the code and wiring, I find that the analogOutputValue is limited to 63, I need the full range of intensities for my particular application.
This was my fault as I changed the wrong line.   :smiley-confuse:



byte sensorValue = 0;        // value read from the pot

Should be:

unsigned int  sensorValue = 0;        // value read from the pot


Edit:
Changes have been made in post #14



No technical PMs.
The last thing you did is where you should start looking.

mlynn

Ah! I actually spotted it this morning and forgot to make the changes to this thread for future viewers!

The issue was the result of a limit of the variable type used.

Thanks for fixing the post. +1 more karma for you wise sage.

For specificity, the unsigned int can store a value much larger than a byte.

Byte is limited to a much smaller size. Refer to the table of integer types and variable types in C language for details.

http://www.zentut.com/c-tutorial/c-integer/


https://en.cppreference.com/w/cpp/types/byte

This limit on the stored values in the byte type caused the looping value behavior previously mentioned.




larryd

"the unsigned int can store a value much larger than a byte. "

Since an analogRead returns always +, 'unsigned' is specified (int=0-65535, but plain 'int' will work too +- 32k).

type                     range
byte                     0-255
char                     -128 to +127
int                       -32,768 to 32,767
unsigned int       0 to 65535 
long                    -2,147,483,648 to 2,147,483,647
unsigned long    0 to 4,294,967,295





No technical PMs.
The last thing you did is where you should start looking.

Go Up