is it possible to only use part of a potentiometer range? in other words..... I have a potentiometer which has a 300 deg. range and i'm wandering if its possible to use only say 100 deg. for actually sending position info.. i'm working on a project where the pot would be connected to a lever. when the lever travels outside the 100 deg. range the pot would simply send a "0" position signal. can this be done? i'm also using a board with the arduino nano w/atmega 328.
So you're using a pot as a poor-man's shaft encoder ?
when the lever travels outside the 100 deg. range the pot would simply hold a "0" position. can this be done?
You're going to have to explain that some other way because the question doesn't make any sense in view of the fact that what you are really saying is that you are reading a pot wiper with an analog input and now your asking if "val>100" if you can let x=0 ?
What does "hold a "0" position." mean ? You imply that you have a mechanical sytem for rotating the pot (lever, whatever).
What are you actually asking ?
sorry about that. the pot is mounted to a lever that simply rotates the pot.. the overall purpose is to power a linear actuator which is set up to receive position signals from a control board like a servo motor. the pot has a 300 deg. turning range. what I need is for the pot to supply a position signal between 200 and 300 deg.. 200 the actuator is fully retracted, 300 the actuator is fully extended. I need it so the pot can be turned below 200 deg. without telling the actuator to move and stay at fully retracted position. can this be done?
An IF statement like this pseudo code would probably get you going.
ReadPotVar = read.PotPin
if (ReadPotVar < 200) then (ReadPotVar = 200)
if (ReadPotVar > 300) then (ReadPotVar = 200)
Do.What.Ever.With.ReadPotVar
There is also a function "restrain" (if I remember correctly) that you might be able to use.
the pot is mounted to a lever that simply rotates the pot
So the actuator is not connected to the pot ? And the pot is not a feedback device, it is a control lever, and you could label the positions "EXTEND" and "RETRACT", right ? (the only thing touching the lever is your hand , right ?
that's exactly right. how would I go about using your suggestion?
#include <LiquidCrystal.h>
#include <LCDKeypad.h>
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
char msgs[5][16] = {"Right Key OK ",
"Up Key OK ",
"Down Key OK ",
"Left Key OK ",
"Select Key OK" };
int adc_key_val[5] ={50, 200, 400, 600, 800 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;
void setup()
{
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" helle! ");
lcd.print(" welcome!");
lcd.setCursor(0,1);
lcd.print(" LinkSprite");
lcd.print(" LCD Shield");
delay(1000);
lcd.setCursor(0,0);
for (char k=0;k<26;k++)
{
lcd.scrollDisplayLeft();
delay(400);
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print("ADC key testing");
}
void loop()
{
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey) // if keypress is detected
{
delay(50); // wait for debounce time
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey)
{
lcd.setCursor(0, 1);
oldkey = key;
if (key >=0)
{
lcd.print(msgs[key]);
}
}
}
delay(100);
}
// Convert ADC value to key number
int get_key(unsigned int input)
{
int k;
for (k = 0; k < NUM_KEYS; k++)
{
if (input < adc_key_val[k])
{
return k;
}
}
if (k >= NUM_KEYS)k = -1; // No valid key pressed
return k;
}
Look at the schematic. See how the buttons are connected to a voltage devider , resulting in a specific range of reading for each key. Look at the code. Notice how there is an array with those range values and a function called Get_Key. That is one approach.
Another way to do it is just use a CASE statement.
1602+LCD+Shield+Sch.pdf (163 KB)
i'm completely lost. that code u gave has to do with a lcd screen and pressing buttons. i'm not able to see how I can use that code in my code. i'm really sorry but i'm completely new at this.
// Convert ADC value to key number
int get_key(unsigned int input)
{
int k;
for (k = 0; k < NUM_KEYS; k++)
{
if (input < adc_key_val[k])
{
return k;
}
}
for (k = 0; k < NUM_KEYS; k++) // For statement that says " for the value "k", let k=0;, As long as k< than NUM_KEYS
(look at the declarations, you see this (int NUM_KEYS = 5;) so as long as k <5, execute the code in the for loop.
if (input < adc_key_val[k]) (What does it say? if input < the value in position [0] of the array adc_key_val
(look at the declarations, do you see this (int adc_key_val[5] ={50, 200, 400, 600, 800 } ?
What is the value in position "0" (correct answer is 50)
( so if you are following this you realize that the array values represent a value GREATER than the voltage that could possibly be measured for that position. Remember when I said this ?
Look at the schematic. See how the buttons are connected to a voltage devider , resulting in a specific range of reading for each key. Look at the code. Notice how there is an array with those range values and a function called Get_Key.
Did you do what I suggested ? Did you look at the schematic ? Do you understand what a voltage divider is ? Do you see that there is only one key that could result in a measurement of less than 50 ? Do you understand what that means ? It means that there is only one position of your lever that could return LESS than the value 50. So what happens if the lever is in position 2 ? What happens in an IF statement if the condition is not met ? It drops out and the counter is incremented . Now k=1. Since k is INDEX for the array, that means the if statement will compare the voltage measured on the wiper of your pot to the next value (200). If the lever is in position 2 (positions start at 1 , not 0), that means that the value will be less than 2 and the condition will be met and the value of k returned will be 1. Try running this code with a potentiometer wiper connected to your analog input. Insert serial print statements in the code to print out the value of key ( key = get_key(adc_key_in); ) Move your lever to 5 different positions. The code will only recognize five . If you go beyond position 5 it will return -1 (meaning no valid key pressed, or in your case, no valid lever position. This process will continue for all 5 positions. If your position 5 does NOT read more than 800 (using the serial print statements you add) when the lever is in position 5, then your pot/lever setup is calibrated correctly. If you make position 5 such that the analog count read is greater than 800 then your system is not calibrated and all your data is invalid. Each lever position MUST NOT read GREATER than the corresponding value in the array. If it is ONE COUNT LESS , IT IS OK. IF IT IS ONE COUNT OVER, IT IS INVALID ! IT CAN BE ANYTHING GREATER THAN THE NEXT LOWEST VALUE IN THE ARRAY)
Ok, let's go through it step by step.
Initial condition: Pot is attached to lever
Pot -pin-1 : => Ground
wiper=> A0 arduino analog input
pin-3=>+5Vdc (arduino 5V pin)
Lever in position -1: wiper voltage = 4V (this is just an example. It doesn't matter exactly what the voltage is because you are
going to change the value in the code to match the value you measure)
Lever in Position-2: wiper voltage = 0.5Vdc (again it doesn't matter if the lever pos 1 and pos 2 are reversed because you can
change that.)
Ok, now look at the code I gave you in my last post. Do you see this ?
int adc_key_val[5] ={50, 200, 400, 600, 800 };
This is the declaration for an integer array containing five values. (Just image you lever has five positions ok ?)(so you can understand it. We will change it later)
Now look at the program in the last post an find this :
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
(this is just a piece of the code to explain it)
Do you see the statement " key = get_key(adc_key_in); : That reads the pot wiper, calls the function to determine the position using the name of the variable as the argument of get_key function. I am not changing anything in the code so you can see why the code applies to your application. Since the key assignment statement is assigning the value represented by the function get_key with value measured on the wiper, that means the program next must run the code for the function get_key to resolve the value of the variable key. // Convert ADC value to key number Now imagine that you have tested the code and verified that it works , you can eliminate THREE of the positions (like the three between 1 and 5, which is 2,3, &4. so now your values are 200 and 800, and you have to delete the three you no longer need from the array and change the array declaration to an array of 2 . Now do you understand ? Now do you realize that EVERYTHING ELSE IN THE PROGRAM I POSTED IN MY LAST POST IS IRRELEVANT (LCD etc. etc. etc.) The only thing relevant is what I just explained. You can delete everything else..But if I deleted it before explaining then you wouldn't realize that when you said
i'm completely lost. that code u gave has to do with a lcd screen and pressing buttons. i'm not able to see how I can use that code in my code. i'm really sorry but i'm completely new at this.
that it was only because you didn't realize how it applied.
You can also use a CASE statement approach:
http://www.arduino.cc/en/Reference/SwitchCase#.Uy0m1vldW_g
wow.....that cleared it up! thanks so much. if your not a teacher of this stuff, you should be! I understand the code now. i'll post again to let you know how it goes.
Thanks, that took a lot of time . I hope you clicked my karma button...
FYI: I reread my post and caught a mistake I made and corrected it. See if you can find what I changed.