Shop OBEX P1 Docs P2 Docs Learn Events
Propeller votlmeter--beginner question — Parallax Forums

Propeller votlmeter--beginner question

This is my very first Propeller project so I'm very much a beginner (I have programmed BS2's in the past). I'm building a multi-function display for my pop-up trailer that will show temperatures (current, hi, low and refrigerator) as well as voltages (solar panel output, battery). The temperatures are no problem but I'm struggling with the voltage part. All I need is a voltage readout with two decimal places. I'm using an MCP3202 (right now with just 5volts, the final will use a voltage divider for up to about 20 volts). I was hoping for an "voltmeter object" to make things easy but I could not find one. I tried to adapt the BOE voltmeter tutorial, but at my stage of learning, it's way over my head.
I've attached what I've done so far, it's very simple and I'm sure there is a better and more accurate way to come up with voltage, but this works. I'd like to limit it to just two decimal places. Any suggestions or help would be appreciated.

Comments

  • The way I did it with my 10-channel voltmeter / logger, with an input of 0 to 20V, was to use a voltage divider to scale the input to 0 to 5V. Then accumulate 1000 samples together and divide by 2048. 4095 x 1000 / 2048 = 1999. My object is written is PASM, hence the simple divide by shifting, and is only intended to monitor a slow-changing voltage where stability is more important than speed.

    I used an array of seven-segment LEDs for the display. For a serial terminal, this method might be helpful:
    PUB fDec(value,divider,places) | i, x
    {{
       Transmit the ASCII string equivalent of a fixed-decimal value
       example usage: serial.fDec(1999,100,2)
       expected outcome of example usage call: Will print the string "19.99" to a listening terminal.
    }}
    
      if value < 0
        || value                                            ' If negative, make positive
        fds.tx("-")                                         ' and output sign
    ' else
    '   fds.tx(" ")                                         ' pad first character to align with negatives
      
      i := 1_000_000_000                                    ' Initialize divisor
      x := value / divider
    
      repeat 10                                             ' Loop for 10 digits
        if x => i                                                                   
          fds.tx(x / i + "0")                               ' If non-zero digit, output digit
          x //= i                                           ' and remove digit from value
          result~~                                          ' flag non-zero found
        elseif result or i == 1
          fds.tx("0")                                       ' If zero digit (or only digit) output it
        i /= 10                                             ' Update divisor
    
      fds.tx(".")
    
      i := 1
      repeat places
        i *= 10
        
      x := value * i / divider                             
      x //= i                                               ' limit maximum value
      i /= 10
        
      repeat places
        fds.Tx(x / i + "0")
        x //= i
        i /= 10    
    
  • If you're comfortable with the MCP320x object, the rest is pretty easy. Assuming that the voltage into the MCP320x is 1/4 the actual voltage. I would convert to hundredths of volts like this:
      raw := adc.read(VOLTS) << 2                                   ' x4 (for voltage divider)
      hvolts := raw ** $1F41_F420                                   ' x0.1221 (raw to 1/100 volts)
    

    As with the ** operator in PBASIC, ** works with fractional values less than 1. Take your fraction and multiply it by 2^32 to get the multiplier for **.

    Are you my friend, Scary Terry, from the Halloween world?
  • Here is a little code snippet that should get you going. I was written for the MCP3208, but just check the pins for the MCP3202 chip instead.
  • Thanks Chris and Jon, I'll work on this tomorrow and hopefully get it going. I'll let you know if I have questions.
    And yes Jon, I'm that Scary Terry. I retired last year and one of my retirement goals is to learn to program the Propeller. I'm finding it much harder than the BS2 but right now I'm taking baby steps in learning it. I hope you are doing well.
  • Thanks PropGuy2, I'll try it out tomorrow.
  • JonnyMacJonnyMac Posts: 9,105
    edited 2016-04-22 15:09
    Thanks Chris and Jon, I'll work on this tomorrow and hopefully get it going. I'll let you know if I have questions.
    And yes Jon, I'm that Scary Terry. I retired last year and one of my retirement goals is to learn to program the Propeller. I'm finding it much harder than the BS2 but right now I'm taking baby steps in learning it. I hope you are doing well.

    Please trust me: In a very short time you will have one of those "Aha!" moments where it will all fall into place and you'll wish everything was as easy to use as the Propeller. I wanted to throw myself out a window yesterday having to do a PIC project for a client -- the problem is my apartment is on the second floor and it just would have hurt, not killed me (and the pain of working with a PIC!). :)

    Just in case I haven't updated ObEx in a while, I've attached my latest MCP320x objects. One of the things I do with these when monitoring joysticks for camera controls is average them (to filter out the noise). If that's of interest I will show you how I do it.

    I am well, thank you. Happy retirement, and have fun with the Propeller!
  • Jon, That certainly is a simple little snippet of code and it returns a four digit voltage, which is what I was looking for, but there is no decimal point. I know I'm missing something (obviously the decimal point), how do I work it into this program?
  • JonnyMacJonnyMac Posts: 9,105
    edited 2016-04-22 15:10
    You can use division and modulus -- as you've done before.

    I'm fussy about terminal displays so I have my own update of FullDuplexSerial which includes a method called rjdec() (right-justified decimal) that was originated by Dave Hein, and has PST formatting codes. My habit is to create an object called "term" that uses this code.
      term : "jm_fullduplexserial"
    

    Most of my programs have a setup() method -- this is where I start the terminal object.
      term.start(RX1, TX1, %0000, 115_200)
    

    Finally, here's how I would code the output based on what you have in your program:
    pri jm_display
    
      term.tx(term#HOME)
      term.str(string("Raw...... ")
      term.rjdec(raw, 4, " ")
      term.tx(13)
      term.str(string("Volts.... ")
      term.rjdec(hvolts / 100, 2, " ")
      term.tx(".")
      term.rjdec(hvolts // 100, 2, "0")
    

    The third parameter of rjdec is the character used to replace leading zeroes; this allows nicely-formatted displays.

    I've attached an archive for my basic template program in case you find it useful. It includes jm_fullduplexserial.
  • Thanks Jon, I'll continue working on it today.
  • JonnyMac wrote: »
    Just in case I haven't updated ObEx in a while, I've attached my latest MCP320x objects. One of the things I do with these when monitoring joysticks for camera controls is average them (to filter out the noise). If that's of interest I will show you how I do it.
    Gotta add that to my collection. To filter noise I used ">> 3" with CASE and I still have to adjust values from time to time. I even put a small electrolytic between ground and 3.3V which didn't help much.
  • Terry: Attached is a version of your program that updates the display every 250ms with the the average of the last four readings. This uses a scheduling type process instead of delays to accomplish timing. This allows you to interleave timed processes that can have a bit of wobble (processes that require critical timing should get their own cog).
  • Thanks Jon and everyone else for your help on this. After several hours of trial and error and a few aha moments, I finally got it working exactly like I wanted. My display now shows the current air temperature, refrigerator temperature, battery and solar panel voltages and a push of a button gives me the high and low air temperatures with the ability to reset those numbers. Now it's time to build the circuit and install it in my trailer. I'm still very much a beginner but looking forward to my next Spin project.
  • Please trust me, Terry, you're in for a lot of fun. Just wait until you start using the Propeller in your Halloween displays.... :)
Sign In or Register to comment.