Shop OBEX P1 Docs P2 Docs Learn Events
trying to read voltage and getting no where :( — Parallax Forums

trying to read voltage and getting no where :(

eagletalontimeagletalontim Posts: 1,399
edited 2009-01-04 22:49 in General Discussion
I am attempting to read 5v DC and less and store 1 through 10 in a variable based on the input. 0 volts would be 1, and 5 volts would be 10. I have tried using the ANALOGIN and the RCTIME and am getting nothing [noparse]:([/noparse] I have tried different SX's and it still does not work. I figure ANALOGIN would be better since the examples say "Voltage to measure". I have everything hooked exactly like the example and I am not getting the slightest reading from it. I have tried using the DEBUG feature and watching the output. It is always 0. All the wires are connected properly with no loose connections. Can someone help me figure why this is not working? For right now, I am using the SX-Tech with the SX28 to do the testing.

Comments

  • eagletalontimeagletalontim Posts: 1,399
    edited 2009-01-04 00:10
    ok, i found I had another pin being changed later in the code.....that is fixed now tongue.gif Now I have a math question. When I used the watch statement, it found that 203 is the lowest it would go and that 243 was the highest it would go. Can someone help me get this into a 1 through 10 digit? Sounds pitiful, but i am struggling with it [noparse]:([/noparse]
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2009-01-04 00:38
    243 - 203 = 40
    !!

    Let's say the results VAR is volts.

    volts = volts-203
    volts = volts/8

    That'll give a result of volts as volts.

    If you want 1 to 10 then divide by 4 instead of 8
  • eagletalontimeagletalontim Posts: 1,399
    edited 2009-01-04 01:18
    well dang.. my idea for a 1 through 10 did not work like i needed it to. I am trying to get the small range of the sensor to be stored in a variable and then convert that to work with the PWM command to adjust the voltage on a solenoid. Since the range is around 40, i was going to use the formula ( is / of = % / 100 ) to get the percentage and then convert that to adjust the pwm command to go from 0 to 150. 0 would be 100% and 150 would be 0% The analogin is not extremely stable so I have to figure out some way to make it more stable if possible. My meter is swinging all over the place right now with what i am using.
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2009-01-04 02:22
    Well, your voltage source (what you're ANALOGIN'ing) shouldn't be hopping around like that.· What's the deal there?· Get that stabilized.


    ·······································50K
    ····························+ 5V ----\/\/\/
    GND
    ·······································
    ······································· |
    ·············· 10K··········· 10K······ |
    ·RA.1 Pin
    \/\/\/----+---\/\/\/
    +
    ························ |
    ·RA.0 Pin
    +--|(--- GND
    ·························· 0.01uF
    ···························"103"
  • eagletalontimeagletalontim Posts: 1,399
    edited 2009-01-04 02:30
    i wound up figuring out how to convert the small range into a 0 to 100% scale. Here is what i have so far :

      ANALOGIN InPin, OutPin, a, 1
      if a < lowa THEN
        lowa = a
      endif
      if a > higha THEN
        higha = a
      endif
      a = higha - a
      of = higha - lowa
      big = a * 100
      big = big / of
      a = big_LSB
      watch big
      watch lowa
    
    



    if there is an easier way to do this, please let me know [noparse]:)[/noparse]

    My next step is to make the 0 to 100 = 255 to 0
  • eagletalontimeagletalontim Posts: 1,399
    edited 2009-01-04 03:04
    is it possible to multiply by a decimal with the SX? I am trying to convert 100% to equal 0 and 0% to equal 255. The only way I know to do that is to do something like this :

    the_byte = 255 * the_percentage
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-01-04 03:08
    Look up the */ and ** operators in the help file. As in PBASIC, these can be used to multiply by fractional values (1/256ths with */, 1/65536ths with **). I tend to use ** when scaling as going from 255 to 100 is a fraction less than 1.0.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2009-01-04 03:26
    ok here is what I got :

    ANALOGIN InPin, OutPin, a, 1
      if a < lowa THEN
        lowa = a
      endif
      if a > higha THEN
        higha = a
      endif
      a = higha - a
      of = higha - lowa
      big = a * 100
      big = big / of
      a = big_LSB / 100
      a = __REMAINDER
      digit = 255 ** a
      watch digit
      watch lowa
      watch higha
      watch big
    



    the variable "digit" is always returning 0. I tried switching to */ and it almost matched the variable "big". I am having a hard time understanding this [noparse]:([/noparse] I really appreciate the help so far! I am learning that is for sure :P What do you think I need to change?
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-01-04 04:04
    eagletalontim said...
    is it possible to multiply by a decimal with the SX? I am trying to convert 100% to equal 0 and 0% to equal 255. The only way I know to do that is to do something like this :

    the_byte = 255 * the_percentage

    Getting used to */ and ** takes a little doing; once you understand them, though, they're very useful with fixed fractional values.

    Percent_2_Value:
      percent = percent MAX 100                     ' limit
      result = 100 - percent                        ' invert range
      result = result */ $28C                       ' x 2.55
    


    Tip: Use */ for values greater than 0.99 and ** for values less than 1.0. Note that both require a word variable, so result in the code above is a word.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2009-01-04 05:06
    Thank you JonnyMac! That worked perfect! One thing I am wondering about is how you got $28C for 2.55? Is there some way i can find other values as well like 1.50 and stuff like that?
  • eagletalontimeagletalontim Posts: 1,399
    edited 2009-01-04 06:08
    ok, I am still having a problem getting the analogin to return a steady result. I am not sure what I am doing wrong. I am running the SX on a project board from radioshack. It is wired up with a 7805 just like I have found by searching on the forums. The ANALOGIN pins are wired exactly how the example shows in the help files and the post above without the 50K. The disc capacitor is a .01uf. The 2 pins used for ANALOGIN are RC.0 and RC.1. I also have RC.2 run to an NPN transistor with a 1k going to the base, it is straight grounded, a 1k coming from the NPN going to the base on a TIP120, a 10K from the TIP120 base to +12v, and a meter hooked to the TIP120 to test the output. I am using a 12v hobbyist battery running the project board so there should not be any fluctuation in voltage. At 50% or higher, the meter is jumping +/- 2 volts. Only when it is at 100% there is no fluctuation.

    *EDIT* : One more thing.... there are no displays hooked up to ensure there is no extra power consumption.

    Here is my code :
    DEVICE         SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
    FREQ         4_000_000
    ID        "Temp"
    
    InPin         PIN     RC.0 INPUT CMOS
    OutPin         PIN     RC.1 OUTPUT
    
    DigCtrl     PIN     RA
    Segs         PIN     RB
    MaxDigit     CON     4
    a         VAR     Byte
    lowa        Var    Byte
    higha        VAR    Byte
    of        VAR    Byte
    digPntr     VAR     Byte 
    display     VAR     Byte(MaxDigit)
    digit        VAR    WORD
    tmpB1         VAR     Byte
    tmpB2         VAR     Byte
    tmpB3         VAR     Byte
    tmpB4         VAR     Byte
    pressure    VAR    Byte
    big        VAR    Word
    
    INTERRUPT 200
    ISR_Start:
    
    Next_Digit:
      INC digPntr                     ' point to next digit
      IF digPntr = MaxDigit THEN '             check pointer
        digPntr = 0                 ' wrap if needed
      ENDIF
    
    Update_Segs:
      Segs = %00000000                 ' blank segments
      READ DigMap + digPntr, DigCtrl         ' update digit control
      Segs = display(digPntr)             ' output new segments
    
    ISR_Exit:
      RETURNINT
    
    PROGRAM Start
    
    Start:
      DigCtrl = %1111                 ' disable all digits
      TRIS_A = %0000                 ' make dig pins outputs
      TRIS_B = %00000000
      TRIS_C = %00000000
      Segs = %00000000
      lowa = 240
      higha = 240
    
    Main:
      ANALOGIN InPin, OutPin, a, 1
      if a < lowa THEN
        lowa = a - 1
      endif
      if a > higha THEN
        higha = a + 1
      endif
      a = higha - a
      of = higha - lowa
      big = a * 100
      big = big / of
      a = big_LSB
      digit = 100 - a
      digit = digit */ $28C
      watch digit
      watch lowa
      watch higha
      watch big
      pressure = digit_LSB
      PWM RC.2, pressure, 200
      tmpB2 = a / 100                 ' get hundreds digit
      tmpB1 = __REMAINDER                 ' save 10's and 1's
      READ SegMap + tmpB2, display(2)         ' get segment map 100's
      tmpB2 = tmpB1 / 10                 ' get 10's digit
      tmpB1 = __REMAINDER                 ' save 1's
      READ SegMap + tmpB2, display(1)         ' get segment map for 10's
      READ SegMap + tmpB1, display(0)         ' get segment map for 1's
    
    
      GOTO Main
    
    SegMap:                                         ' segments maps
      DATA  %00111111                               ' 0
      DATA  %00000110                               ' 1
      DATA  %01011011                               ' 2
      DATA  %01001111                               ' 3
      DATA  %01100110                               ' 4
      DATA  %01101101                               ' 5
      DATA  %01111101                               ' 6
      DATA  %00000111                               ' 7
      DATA  %01111111                               ' 8
      DATA  %01100111                               ' 9
    
    DigMap: ' digit select map
      DATA %11111110
      DATA %11111101
      DATA %11111011
      DATA %11110111
    



    I appreciate the help!

    Post Edited (eagletalontim) : 1/4/2009 6:14:33 AM GMT
  • eagletalontimeagletalontim Posts: 1,399
    edited 2009-01-04 14:15
    still have not figured out how to get other values like $28C = 2.55 and still cannot figure out why the analogin is returning unstable results [noparse]:([/noparse] Any help would be appreciated!
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-01-04 14:25
    Take your fractional value, like Pi (3.14) and multiply by 256 as */ works in units of 1/256th. For Pi you would get 804 which is $0324. The reason I use hex notation is that it's easier to see the whole part (MSB) and the fractional part (LSB).

    ANALOG in works so it must be something on your end. Don't assume your connections are correct if you're getting bad values; rebuild the circuit. After you've done that verify it with known inputs. I always do this with ADC circuits, testing with 0, 2.5, and 5 volts.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2009-01-04 14:40
    wow....i should have listened in math tongue.gif I found a hex to decimal converter a minute ago and will try that out. I got confused when you said 804 = $0324.

    With the analogin, I have tried on 2 different boards and both boards gave jumpy results. It does not jump much, but 2 volts on the output is a big matter on what I need to get accomplished. I also set up the same circuitry on the SX-Tech and ran the debug to see if it would give steady results. I did not. I got frustrated with it last night and just went to bed to sleep on it. I reassembled everything this morning and it still does the same thing. I can step back 5 feet away and watch the meter still bounce even after letting it sit for 30 minutes or more [noparse]:([/noparse]
  • eagletalontimeagletalontim Posts: 1,399
    edited 2009-01-04 18:05
    is $20 in hex = to 200?
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2009-01-04 18:16
    Nope.·

    $20 = 32

    That·is (2 X 16) + (0 X 1) = 32 + 0

    $33 = 51;

    (3 X 16) + (3 X 1) = 48 + 3 = 51

    $4C = 76

    (4 X 16) + (12 X 1) = 64 + 12 = 76

    Post Edit --
    $324 is equal to 804

    (3 X 256) + (2 X 16) + (4 X 1) = 768 + 32 + 4

    804 / 256·≈ 3.1406 ≈ pi

    Post Edited (PJ Allen) : 1/4/2009 6:22:59 PM GMT
  • pjvpjv Posts: 1,903
    edited 2009-01-04 18:28
    Hi Eagle:

    The software A/D converter is very picky about precise timing....... it relies on balancing aggragate high durations and low durations of a simple R/C Digital to Analog converter (in this case a specialized PWM). Any changes in interrupt durations at runtime will adversely affect the results.

    I see in your code you are using WATCH statements. The A/D conversion will not work if those are active as the time interruption to display them corrupts the strict timing requirements.

    I use my own assembler version of A/D all the time, and it works well. With some tweaking you can get it stable to 12 bits or more.... that is 1 part in 4096. And with some filtering/averaging approach 16 bits!

    If as you say, everything is correct, and the source is indeed stable, then the only thing left is timing inconsistencies.

    Cheers,

    Peter (pjv)
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2009-01-04 18:34
    When eagletalontim said...
    My meter is swinging all over the place right now with what i am using,
    I thought he meant his voltmeter/multi-meter.
    Is ANALOGIN any good with internal RC, or should that be done only with XTAL/OSC/Resonator ?
  • Shawn LoweShawn Lowe Posts: 635
    edited 2009-01-04 18:51
    Eagletalontim-
    Yeah, converting between Hex and Decimal always makes my head go *Sproing!*. Just use the calculator on your laptop/computer. Put it in scientific mode. It should default to decimal. Enter the number you want to convert and hit the Hex button presto bango, there you go. Or, you could do it like PJ Allen did as a good excercise, both ways work. There are numerous examples of */ and ** in the PBASIC help file as well, I think it even shows using a hex value as a mulitiplier factor.
    I've never understood how hex was easier to read than decimal, but I imagine if your work on Micro's alot like Johnnymac, you would eventually prefer to see a hex value (i.e. the LSB and MSB). Keep at it!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Shawn Lowe


    When all else fails.....procrastinate!
  • eagletalontimeagletalontim Posts: 1,399
    edited 2009-01-04 21:13
    I tried what you said Shawn and the calculator would not return 28C as the hex when entering 2.55. That is where I am totally lost. Say I want to convert 1.40 to hex, what would that be? Now that i have my code getting a 1 through 100% for the range of the sensor i am testing, I need to take that percentage and multiply it by 255 or "Max_Value_That_I_Need". I have no idea how to convert a byte variable to a decimal hex that can be multiplied by a preset variable.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2009-01-04 21:23
    ah ha....i think i got it [noparse]:)[/noparse] Thank you soooooo much for the help! Be prepared for more questions...I have a feeling i will have many more to come tongue.gif
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-01-04 22:05
    Again... if you want to convert a fractional number for use with */ you must first convert to units of 1/256ths -- easily done by multiplying by 256. Now you convert to HEX notation. 1.40 x 256 = 358 = $0166. See the $01 MSB? -- that's the whole part of your value; the $66 is the fractional part. $66 = 102, 102 / 256 = 0.398. Yes, there will be a little bit of rounding, but this usually isn't a problem.
    eagletalontim said...
    I tried what you said Shawn and the calculator would not return 28C as the hex when entering 2.55. That is where I am totally lost. Say I want to convert 1.40 to hex, what would that be? Now that i have my code getting a 1 through 100% for the range of the sensor i am testing, I need to take that percentage and multiply it by 255 or "Max_Value_That_I_Need". I have no idea how to convert a byte variable to a decimal hex that can be multiplied by a preset variable.
  • eagletalontimeagletalontim Posts: 1,399
    edited 2009-01-04 22:24
    let me make sure I got this...... I am using the scientific calculator on windows. In hex mode, I enter 20C. When I press Dec mode, it gives me 524. 524 / 256 = 2.05. So basically $20C equals 2.05 on the SX?
  • JonnyMacJonnyMac Posts: 9,214
    edited 2009-01-04 22:49
    eagletalontim said...
    let me make sure I got this...... I am using the scientific calculator on windows. In hex mode, I enter 20C. When I press Dec mode, it gives me 524. 524 / 256 = 2.05. So basically $20C equals 2.05 on the SX?

    Only when using the */ operator. The SX/B help file describes how it works.
Sign In or Register to comment.