Making a LED brighter or less bright with a basic stamp and tilt sensor.
Keith Hilton
Posts: 150
in BASIC Stamp
I would like to see an example of how to use a basic stamp and "tilt sensor" to make a LED brighter or less bright with a basic stamp.
Comments
https://www.parallax.com/product/28036
kwinn, yes, I know I was doing really good. Worked my way through "difficult" code, and experiments, in 4 Parallax books, and two other books on the Basic Stamp. Suddenly realized that all the programs I had been working with only involved stuff leaving the Basic Stamp and displaying on the debug screen. It was at that point I realized I did not know how to actually use the numbers appearing on the debug screen. Yes, I worked out the very complex code for the Memsic 2125 in the Parallax book, and got the correct numbers to appear on my debug screen. After all this hard work it was very discouraging that I could not write simple code to use the numbers appearing on the debug screen in "real life". That is why I ask for help in seeing how I can use the numbers to do the simplest of things---dim the light of a LED, with the tilt sensor. I have read in several places that the Basic Stamp can only do one thing at a time. Does that mean if it measures tilt, then it can not dim an LED with the tilt measurement?
No. Several things can be done in a loop fast enough that they appear to be done at the same time. This is how single cpu chips run multiple tasks.
For dimming a led with the tilt measurement you would have a program loop that inputs the tilt measurement, converts the reading (between 1875 and 3125) to a value between 0 and 255, and uses that value in a PWM instruction as shown below.
PWM Pin, Value, Cycles
Pin would be the pin the led is connected to
Value would be the calculated value between 0 and 255
Cycles would be 255
You could even use the X and Y inputs to control two leds.
Should be easy to do. Your prior code took you 90% of the way there. All that is left is to remove the subtraction of 127 from the calculation, add the PWM line, and put them in a loop. Good luck, and hang in there.
'{STAMP BS2}
'{PBASIC 2.5}
x VAR Word
y VAR Word
DEBUG CLS
DO
PULSIN 6,1, x
PULSIN 7,1, y
x = (x MIN 1875 MAX 3125) -1875 **13369 'x Duty Value 0 to 254, or 1250 times .20399=254.99
y = (y MIN 1875 MAX 3125) -1875 **13369 'y Duty Value 0 to 254, or 1250 times .20399=254.99
PMW 4, x, cycles 'Output to a analog voltage PWM filter circuit.
PMW 5, y, cycles 'Output to a analog voltage PWM filter circuit.
PAUSE 100
LOOP
OK---the number of "Cycles" I list depends on the resistor and capacitor values in the PWM filter circuit I build that leaves the Basic Stamp pins 4, and 5 Charge time for these values is the formula: Charge time= 4*R*C
kwinn, you say "Cycles" would be 255. I do not think that is correct, because the steady output state of the pin would change the voltage on the capacitor and undo the voltage setting established by PWM. Charge time for the BS2 is once cycle equals 1ms. I understand that cycles depends on how much current is drawn from the external circuit, and the leakage of the filter capacitor. Charge time for a LED with a current limiting resistor should be much different than charge time for the input of an OP Amp. I do not know how to figure "Cycles" to put in the above code?
How would I figure cycles for a LED with a 1K current limiting resistor? How would I figure cycles for the input of a non inverting OP Amp? Also, do I need the pause, before the LOOP at the end? How much of a pause?
kwinn, thanks for pointing me in the right direction.
So I need to know how to figure the "cycles" I will need in the code. Since "cycles" is very dependent on current drain, suppose I am feeding the analog voltage 0 to 5 volts DC to a very high impedance load---like the input of an op amp.
Sorry, can't help you there. No Stamp to test with. All I can suggest is to do a little experimenting by building the circuit and trying various cycle values.
What I did next got really interesting. I concentrated on one axis of the tilt sensor. The voltage output was pretty unstable, and would varying from 2.03 to 2.40 volts when the tilt sensor was level. I then ran the output voltage to a buffer op amp, and that cleared up the voltage jumping around. When the sensor was level, with the buffer, the voltage stayed pretty constant at 2.5 volts. Tilting the sensor up the voltage would drop down close to zero. I tried the code without the PAUSE in the code, and the variable voltage output worked quicker and more reliable. Changing the cycles seemed to make little difference unless I got the number real low. I tried changing both the filter capacitors, and resistors in the PWM filter circuit, and that seemed to make little difference. Seemed to work better with a 10K resistor and .1uF capacitor. The variable voltage is not doing exactly what I want. I wish I could get the level voltage to be 4 volts. Also would like the voltage to drop quicker with less movement of the tilt sensor. I could increase the voltage by having the buffer op amp have gain. But I wonder if there is a simpler way with the code, or components in the circuit? At this point I don't know how to make the voltage drop quicker with less movement of the tilt sensor? Right now I almost have to go vertical to get the voltage to drop down to the .3 volt range. I would like to cut that angle down to 45 degrees, or less, to get the voltage to drop to the .3 volt range. Does anyone have a solution to increasing the voltage, besides the buffer? Also--and most important---does anyone have a suggestion of how to make the voltage drop quicker with less of a tilt angle? This is real important---I need the tilt angle to be less, and drop the voltage quicker?
I will have to run some tests and try to get the analog 5 volts instead of the 2.5 volts.
I think I figured out how to make the analog voltage drop quicker when I tilt the tilt sensor. I am pretty sure the scaling code is the answer. I was using a scale code too large. I am going to lower the scale code and see what happens. This should make "big" changes as it is the "DUTY" part of the PWM command.
I have been using the Parallax Memsic 2125 senor, which is two axis. I am actually wanting a single axis version of this. Does anyone know where to get a single axis version of this type of sensor?
What is strange about the Memsic 2125 is it reminds me in some ways of Honeywell's Hall Effect Wheatstone bridge. One big difference would be that you would have to add a magnet to get the Hall Effect Wheatstone bridge to work, and with the Memsic you don't need a magnet. I still worry about what will happen if the Memsic gets bumped or jarred? Does the gas bubble then cause problems---or voltage jump?
I wonder how many people have been following my study and experiments. Sometimes I feel like kwinn is the only one following what I am doing. I guess most people are into robots and the more powerful hot micro-controllers.
I am wondering if there is a better way to convert the digital output of the Memsic 2125 to an analog voltage, other than using the PWM command?
You could always use a digital to analog chip for that. To understand why the analog voltage may differ from the reading on the debug screen you need to understand how to convert values from the voltage, current, or other output to units of whatever you are measuring. You also need to understand how to perform calibration on the sensor and associated electronics.
' {$STAMP BS2}
' {$PBASIC 2.5}
'Getting analog voltage from the memsic 2125
'
[Declarations
x VAR Word
y VAR Word
DEBUG CLS 'Start display
'
[Main Routine]
DO
GOSUB Memsic
GOSUB DAC
LOOP
'
[Subroutines]
Memsic:
PULSIN 6,1,x
PULSIN 7,1,y
x = (x MIN 1875 MAX 3125)-1875 **13369
y = (y MIN 1875 MAX 3125)-1875 **13369
RETURN
DAC:
PWM 4,x,40
PWM 5,y,40
RETURN
kwinn, thanks for your input.
kwinn said: "Changing the scale code will not help. The duty cycle input to the PWM command must be a number between 0 and 255. You need to read up on how PWM is used for controlling power and for producing a variable voltage or current."
kwinn, I have been reading up on how PWM is used. I used a circuit for the PWM consisting of a 10K resistor, and 1uF capacitor to Vss. I buffered the output with a 358 op amp. From my code above, the Memsic 2125 is spitting out the positive numbers 0 to 255. I am only using the x value in the PWM. The x value in my code is the "duty" part of the PWM. You can change the duty, by changing **13369, and it will change the voltage.
Examples in the Parallax book concerning PWM, and a variable output voltage, have code where the "duty" part of PWM is a fixed number. By changing this fixed "duty" number in PWM the voltage changes. The problem with using a fixed number, is it makes the Memsic part useless. I can put in some random "duty" number in the PWM command in the code---and the output will have no relation to the Memsic 2125. x in the code above is not a random number picked by me. x in the code above is a random number picked by the Memsic 2125.
Kwinn, if there is something I am not seeing about how to use the PWM command, then please tell me. By the way, in the code you will see I used 40 as the PWM "cycles". This is because of the 10K resistor and 1uf capacitor.
By the formula for cycles in PWM Cycles=4 X.000001X10,000=40X10-3=40ms.
There should be a way to control PWM better with the Memsic 2125.
kwinn, as you suggested, maybe I need to look into using a DAC instead of PWM. kwinn, I want to thank you for all the help you have tried to give me. Thanks!
Except for the formula for cycles your code and calculations look OK. According to page 356 PWM cycles should be 5 x 0.000001 x 10,000 = 50ms so at 1ms per cycle it should be 50 cycles for a BS2. That would make the PWM statement: PWM 4, x, 50
Are you using a BS2?
What I would suggest is using something to hold the memsic in four or five stable positions and record several values of x and the corresponding voltmeter readings for each position.
One potential problem is the capacitor. It should be a good quality film capacitor. Electrolytic capacitors have high leakage currents that can affect the readings.
Kwinn, I went back to the Parallax book: "Basic Analog and Digital" Version 1.3. My circuit is "exactly" like the circuit pictured on page 133, except for the ADC0831 part. I kept looking at that circuit on Page 133 and thinking.
On the debug screen pictured at the bottom of page 133, they list a DVM reading of 3.25 volts. So if the debug screen lists 3.25 volts, I should be able to put a volt meter on pin 6 of the ADC0831, to Vss and get a reading of 3.25 volts. This is really screwing up my thinking. In my circuit, the Memsic 2125 is feeding digital numbers to the 10K resistor, 1uf capacitor that makes a digital to analog output. The LM385 then feeds a buffered voltage to the LED, and on to pin 2 of the ADC0831. Then the debug screen is saying the output on pin 6 of the ADC0831 is 3.25 volts.
I thought the ADC put out a digital signal from pin 6. So if you are getting a voltage reading of 3.25, it must be a DC voltage with a "lot" of ripple. Once I figured out how to use the Memsic 2125, I planned on using it with a voltage controlled amplifier IC chip. The voltage controlled amplfier IC chip is designed for DC voltage, and I don't know how much ripple it can handle and still work. Wouldn't the output voltage from pin 6 of the ADC0831 be like a square wave voltage?
You talked about me using a dedicated digital to analog converter, DAC "IC", instead of the simple resistor and capacitor. In all of my Parallax books, I don't remember seeing any DAC used. Do you know of a Parallax book that have examples of using a "IC" DAC with code?
I can get the Memsic 2125 working with the code above, and the circuit mentioned above. I have got a decent range of volts to work with concerning using it with the voltage controlled IC. The exact problem I am having is not being able to "dial" in exactly the range I want with the PWM code. I can use voltage dividers to make the range of voltage from the Memsic 2125 work---but----I don't want to do that. I want to be able to "dial" in the voltage range I want with code. I should be able to do that without the code being that complex, as it is not that complicated of a problem. Kwinn, just remember this one thing: "Every thing in electronics boils down to voltage and current". No matter how complex the problem, it winds up about being voltage and current.
It is a digital signal. The debug screen says 3.25V because the BS2 is printing out the decimal value of the digital data it receives from pin 6 of the ADC0831.
Sorry Keith, but just about everything you posted in this last little bit is leading you down the garden path. While voltage and current is important it is not everything, particularly when dealing with digital circuits and computers.
Take the memsic2125 for instance. It converts the angle of tilt into digital values for the x and y axis. Those numbers have values that should range from 1875 to 3125. Those are nominal values. To be sure the memsic is working properly you need to test it over the full range of tilt on both x and y axis, and verify that the input from the memsic goes from 1875 to 3126, and that the output from the calculation goes from 0 to 255. Have you done that test?
To narrow your range, you need to modify these formulas:
x = (x MIN 1875 MAX 3125)-1875 **13369
y = (y MIN 1875 MAX 3125)-1875 **13369
The total range there is 1250. Subtracting 1875 gives the values from 0 to 1250, and **13369 compresses the range to 0 to 255. (**13369 is internally equivalent to 13369/65536 -- You can have almost the same result with a simple /5).
Say you determine by experiment that you want the range from 2000 to 2400.
x = (x MIN 2000 MAX 2400)-2000 */ 163
y = (y MIN 2000 MAX 2400)-2000 */ 163
The */ 163 compresses the 400 range into 0 to 254. I used the */ instead of ** just for convenience and to illustrate that there is more than one way to skin the memsic. */163 internally is equivalent to 163/256, and you can (or the BS2 can) calculate the */ value to use with the following formula:
.....factor = 65535 / (full scale range).
e.g. 65535 / 400 = 163 plus change.
You are right to use the op-amp buffer for holding the voltage while the BS2 is off doing other things. On the other hand the brightness of an LED is a bit harder. LED light output is better driven by a current source. The op-amp circuit can be modified to do that. Another factor is that our eye responds more to the logarithm of the light power output. Perception is relative to the ambient light level. But first things first.
Oh, one last thing: In the many Parallax books I have, I can't find one example of using a DAC IC with code. In the books everything that leaves the Basic Stamp winds up on the Debug Screen. There has to be at least one Parallax book describing a DAC IC example with code? I am not talking about a resistance ladder with a buffer, I'm talking about a dedicated DAC IC example. Is there such a thing in all the Parallax teaching material?
Another option for you might be a digital potentiometer.
Now getting back to the numbers the Memsic 2125 puts into the basic stamp.
x = (x MIN 1875 MAX 3125)-1875 **13369
y = (y MIN 1875 MAX 3125)-1875 **13369 I thought these numbers were the Duty of the format for the PWM command. I can change the range. x = (x MIN 2000 MAX 2400)-2000 */ 163
y = (y MIN 2000 MAX 2400)-2000 */ 163
Maybe I have everything wrong, maybe these are not the "duty" numbers. Where in the world does PERIOD come in?
Duty Cycle is defined as: On-Time divided by the period. I have no idea what the period is? I have no idea how to select the resistor and capacitor values of the DAC to leave no ripple or AC, because I don't know how to figure the frequency of the PWM. I also don't understand if there is a pause or time requirement in the code depending on the DAC filter components. After reading all the material in two parallax books concerning PWM, I don't have a clue as to how to write the code. Nor do I understand what or how to figure the duty cycle. I don't understand what is meant by cycles in the format, when it is used in a different context Duty Cycle. Can someone clear this mess up for me? All I am wanting is something real simple. I just want a variable analog voltage from the circuit using the Memsic 2125. Why does this have to be so complex and confusing?
The typical PWM signal is really simple. The basic signal is a square wave, so the output is either at 0V or at full voltage. For a 5V chip like the Basic Stamp that would be 0V or 5V.
Pulse width modulation outputs the pulses at a fixed frequency, so each pulse starts a fixed time from the start of the previous pulse. That is the period, which is 1/frequency.
Now connect that signal to a 1K resistor. If you connect 5V to a 1K resistor you would get a 5mA current flowing through it which would result in 5V x 5mA = 25mW power to the resistor.
Now instead of a fixed 5V lets say we have a 5V PWM signal at a frequency of 1KHz across that 1K resistor. That signal would have a period of 1mS. If that signal square wave was high for 0.5mS and low for the rest of that 1mS period the resistor would get 5V x 5mA x 0.5 = 12.5mW since the power is applied for half the time. The duty cycle would be 0.5mS (on time) / 1mS (period) or 50%.
If the on time changed to 0.25mS the applied power would be 6.25mW and the duty cycle would be 25% ( 0.25mS / 1.0mS ).
When the PWM signal is applied to a filter circuit like the 10K-1uF circuit you used the capacitor is charged during the on time and discharged during the off time. The end result is that after 5 RC time constants the capacitor is charged to 5V x on time / period. The RC time constant is R x C which in this case is 10,000 x 0.000001 = 0.01Sec or 10mS. Multiply that by 5 and you get the 50 cycles required by the Stamp PWM instruction.
I’m guessing the 1mS time for each cycle is how long the Stamp firmware takes to execute the PWM instruction code. This cycle value is needed to allow for different values of R and C in the filter circuit.
Finally, the 0 to 255 range rather than using a percentage must be for ease of programming and providing finer control over the duty cycle. Percentage provides a resolution of 1 part per 100, while using an 8 bit binary value provides a resolution of 1 part per 256 with no increase in memory use or program complexity.
You are correct that expressions like
x = (x MIN 1875 MAX 3125)-1875 **13369
or
y = (y MIN 2000 MAX 2400)-2000 */ 163
give the number to plug into the duty parameter.
The choice of R x C governs how fast the buffer will respond to changes at the input. It also governs how much ripple will be left in the output after filtering. When the duty value is either near zero or near 255, it becomes harder to filter. It requires a larger value of R x C and more cycles to reach a steady state. On the other hand, duty values near 128, or say in the range from 32 to 224 are much easier to filter and require fewer cycles.
I am going to use the "Duty" parameter x = (x MIN 2000 MAX 2400)-2000*/163 The extremes of the Memsic are 1875 to 3125, and the tilting I am going to be doing is in the range on 15 to 30 degrees max, down to zero degrees on one axis. Figuring the "CYCLES" in the PWM format with the resistor and capacitor values in the filter circuit may be the most difficult. At the extremes of the "Duty" parameter--Duty 1 or Duty 255-- more filtering through many cycles is required. The least filtering is required with the Duty parameter being 128, which is in the middle. For Duty 1 or 255 a minimum of 200 pulses. For duty 128 only one pulse.
RXC product must contain at least 200 pulses for the lowest expected frequency. With the "x" duty parameter listed above, we are still dealing with 0 to 254. 400x163/256=254 The filtering required is all relative to how much ripple you can get away with. Each cycle on the BS2 takes .00115 seconds. If you use the figure 100 for cycles, the time required for the BS2 is 100x.00115 seconds, which equals = .115 seconds. The formula for resistor capacitor charge time is 4*R*C. So a value of 4x10,000x.000001= .04 seconds. So using cycle at 100, with the values of 10K and .1uf----filter network gets charged in .04 seconds, and the basic stamp is doing it's work in .115 seconds. If anyone sees a flaw in my figures, or thinking, please point the mistakes out. From what I am seeing, the size of the resistor and capacitor, plus the cycle number "ALL" depend on the range I tilt the axis in my application, and the amount of ripple in the DC I can get away with.