I'm fairly new into this so please excuse any dumb thing I may ask...
I'm building a small led strip controller. I've install those strips on my house and I'm planning to have different setup for Halloween, Christmas, St-Valentin...
I've program different routine for those events and I've install a rotary switch with 10 positions. There are 5 pins on that switch. I've been able to map the different position of the switch (like 0 = pin 1, 2 = pin 2, 3 = pin 1 and pin 2...) I've put 4 different resistors on 4 of the pin and connect the 5th pin to an analog pin of my Arduino Uno.
With some experimentation, when reading the analog pin, I've been able to come up with some range and can call the appropriate routine.
My problem is that those readings are inconsistent (depending on how many lights are ON of OFF) and the power supply I'm using.
Is there any way to "stabilize" those readings so they will always be the same. I'm not expecting to have an exact value and won't mind using a range but right now my ranges are not good enough.
The best way to stabilize the readings is to use a separate power supply for the lights (be sure to connect the two power supply grounds together). If you can't do that, read up on "power supply decoupling" -- you need additional filtering on the Arduino power supply.
FYI - I hate the idea of using analog for something that's actually digital....
What are the readings from the ADC, and how much do they vary? It shouldn't be that hard to get 5 completely different readings.
Is your sketch looking for an exact reading, or for a range? I think it can work if you look for a range of values, or simply use greater-than or less-than. If you have values that go from 0 to 1023, the values should be distinctly different and far enough apart so this can work.
I understand that he tries to identify the switch position
but I'm afraid we won't be helpful without a schematic . Maybe the power supply can't deliver enough current and the voltage drops when several strips are on
alnath:
I understand that he tries to identify the switch position
but I'm afraid we won't be helpful without a schematic . Maybe the power supply can't deliver enough current and the voltage drops when several strips are on
Ahh cheers
An input for each switch position instead.
Detect which one is high, if none then it is off?
I've program different routine for those events and I've install a rotary switch with 10 positions. There are 5 pins on that switch. I've been able to map the different position of the switch (like 0 = pin 1, 2 = pin 2, 3 = pin 1 and pin 2...) I've put 4 different resistors on 4 of the pin and connect the 5th pin to an analog pin of my Arduino Uno.
Alternate connections: An R2R ladder will give equal steps in voltage at it's output.
Here, the steps in VOUT are equal at 1/3 volt per step:
dlloyd:
Here, the steps in VOUT are equal at 1/3 volt per step:
I don't think so!
An R-2R ladder depends on negligible input impedance to the 2R sections. In this case however, you are switching not rail-to-rail, but between one rail and open, so that the impedance of the ladder varies with the number of resistors actually switched in. Let me examine the above. No switches on, output is zero. "1" on - output is 1/2 of 5V. "2" on - output is 3/5 of 5V. "1+2" - output is 3/4 of 5V, "4" on - output is 2/3 of 5V.
Did I miscalculate something there? Will check later.
Did I miscalculate something there? Will check later.
You're right ... was thinking active logic type, however opened contacts are high impedance. They should ideally be at GND potential.
If R=10K and 1K pull-down resistors added to 1,2,4,8, then it would work with 1/3V steps ±10%. Although easy to detect each step, we're now up to 12 resistors. However, through-hole 10K/20K R/2R network SIP resistors are available + another SIP for the pulldowns, bringing it to 2 additional external components.
Oh well, the idea is to get equal steps in VOUT ... but not sure how practical or economical the solution is.
EDIT: Non-overlapping steps seems the best that can be achieved without use of an op-amp.
Well, the OP seems to have deserted us - not an uncommon event - and I stick to my original reply that we need to know his actual circuit arrangement and whether he had the necessary pull-up resistor to start with, in the absence of which performance would be very unstable.
With that resistor, it is not particularly difficult to have four resistors, one to each switch pole, with binary progressive values. Unless you provide a constant-current source, the voltage steps will not be linear, but if the pull-up is significantly higher than the largest "binary" resistance value, it may be practical for a direct division/ shift operation to scale the result into a value from 0 to 15 suitable for a "case" routine.
In fact, the internal pull-up probably behaves in a somewhat constant-current mode and would be the best choice.
sorry for the long delay... my life is not as quiet these days as I'd like it to be... here are some clarifications.
I'm using an old computer power supply to feed the 12v and 5v.
I've connected 4 different resistors to 4 of the rotary pins (910k, 250k, 820k and 220k) and a 100k to the ground and analog pin5
To experiment with the button, I first built a small prototype with only the button and I was sending the values to the serial output. Then I've test twice with my full project (including a LCD screen to be able see the actual values used when trying to balance the LED): all LED off and then all LED on. This is what each position of the switch was reading:
Res = Resistors combinations
Test1 = Rotary button only
Test2 = Rotary button, all LED off
Test3 = Rotary button, all LED on
As you can see, once the LED are turn on, there is a big difference and the readings will vary from everything off to everything on...
Here is a diagram of my controller (I was not able to find an actual rotary switch so I've used the 1st object I could find with 5 pins and the LED are on a strip, not just 3 single LED...)
and just in case here is the diagram of my LCD module:
and here is a simplified version of the the source code (I've put the button identification in comment because I can't used it anymore, too much variation...)
#define SHIFTPWM_USE_TIMER2 // for Arduino Uno and earlier (Atmega328)
const int ShiftPWM_latchPin=8;
const bool ShiftPWM_invertOutputs = false;
const bool ShiftPWM_balanceLoad = false;
#include <ShiftPWM.h> // include ShiftPWM.h after setting the pins!
unsigned char maxBrightness = 255;
unsigned char pwmFrequency = 75;
unsigned int numRegisters = 2;
unsigned int numOutputs = 9; //numRegisters*8;
unsigned int numRGBLeds = 3; //numRegisters*8/3;
unsigned int fadingMode = 0; //start with all LED's off.
unsigned long startTime = 0; // start time for the chosen fading mode
int pot1Pin = 1;
int pot2Pin = 2;
int pot3Pin = 3;
int buttonPin = 5;
int calibPin = 4;
#include <ShiftLCD.h>
ShiftLCD lcd(2, 4, 3); // orange - yellow- green
int reading, oldButton;
char *fonction[10] = {
"Test HVS", // 0
"Test RGB", // 1
"Halloween", // 2
"Noel", // 3
"St-Valentin", // 4
"Menu 5", // 5
"Menu 6", // 6
"Menu 7", // 7
"Menu 8", // 8
"Menu 9" // 9
};
char *label[2][3] ={
{"Hue:","Saturation:","Brigthness:"},
{"Red:","Green:","Blue:"},
};
int myButton;
int pot1Value, pot2Value, pot3Value;
void setup(){
Serial.begin(9600);
lcd.begin(20, 3); // set up the LCD's number of rows and columns:
// Sets the number of 8-bit registers that are used.
ShiftPWM.SetAmountOfRegisters(numRegisters);
// SetPinGrouping allows flexibility in LED setup.
// If your LED's are connected like this: RRRRGGGGBBBBRRRRGGGGBBBB, use SetPinGrouping(4).
ShiftPWM.SetPinGrouping(1); //This is the default, but I added here to demonstrate how to use the funtion
ShiftPWM.Start(pwmFrequency,maxBrightness);
checkButton(0);
ShiftPWM.SetAllHSV(0,0,0);
}
void loop()
{
checkButton(1);
TestColor(1);
}
void TestColor(int labelNumber){
pot2Value = analogRead(pot2Pin)/4;
delay(100);
pot3Value = analogRead(pot3Pin)/4;
delay(100);
if(myButton==0){
pot1Value = constrain(analogRead(pot1Pin)/2.8,0,360);
ShiftPWM.SetAllHSV(pot1Value,pot2Value,pot3Value);
} else{
pot1Value = analogRead(pot1Pin)/4;
ShiftPWM.SetAllRGB(pot1Value,pot2Value,pot3Value);
}
delay(100);
}
void checkButton(int labelNumber){
// 910k
// 250k
// 820k
// 220k
reading = analogRead(buttonPin);
Serial.println(reading);
delay(500);
/*
if(reading >= 0 && reading <= 25){ // 0
myButton = 0;
}else if(reading >= 140 && reading <= 155){ // 1
myButton = 1;
}else if(reading >= 405 && reading <= 420){ // 2
myButton = 2;
}else if(reading >= 445 && reading <= 465){ // 3
myButton = 3;
}else if(reading >= 170 && reading <= 185){ // 4
myButton = 4;
}else if(reading >= 255 && reading <= 265){ // 5
myButton = 5;
}else if(reading >= 472 && reading <= 490){ // 6
myButton = 6;
}else if(reading >= 500 && reading <= 520){ // 7
myButton = 7;
}else if(reading >= 95 && reading <= 115){ // 8
myButton = 8;
}else if(reading >= 196 && reading <= 206){ // 9
myButton = 9;
}
if (myButton != oldButton){
lcd.clear();
oldButton = myButton;
}
*/
DisplayLCD(labelNumber);
}
void DisplayLCD(int labelNo){
lcd.clear();
lcd.setCursor(1,0); lcd.print("Reading");lcd.setCursor(15,0);lcd.print(reading);
lcd.setCursor(1,1); lcd.print(label[labelNo][0]); lcd.setCursor(15,1); lcd.print(pot1Value);
lcd.setCursor(1,2); lcd.print(label[labelNo][1]); lcd.setCursor(15,2); lcd.print(pot2Value);
lcd.setCursor(1,3); lcd.print(label[labelNo][2]); lcd.setCursor(15,3); lcd.print(pot3Value);
}
During all that testing, I kept the USB cable connected to the computer, so the board was receiving power from the USB port and the power supply. When I unplug the USB and only look at the results on the LCD screen, it is even worst. The LCD goes from very bright to very dim.
My problem is that those readings are inconsistent (depending on how many lights are ON of OFF) and the power supply I'm using.
In the past better reading stability has been achieved by reading the input twice instead of just once, and using the second read as the input. Maybe something like below
Yes, clearly those original values were silly, not just because they were too high in value (which probably does not matter so much) but because they were not sufficiently scaled.
For practical resistor values, let's say you use a 10k for the ground resistor (which sets the impedance into the analog input, 10k is fine), then a 22k for the "8", 47k for the "4", 100k for the "2" and 220k for the "1".
Note - the lack of a ground connection is more likely the real problem here.