1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

2 voltmeters using a single microcontroller

Discussion in 'Microcontrollers' started by BM8, Sep 11, 2017.

  1. BM8

    BM8 New Member

    Joined:
    Sep 11, 2017
    Messages:
    3
    Likes:
    0
    Hi all,

    I need some help with a certain digital voltmeter circuit design. I should start by saying that I’m new to electronics so any detailed explanation would be highly appreciated.

    I’m trying to make a circuit to measure voltage from 2 DC sources in series, using 1 microcontroller. Here is a sketch of the circuit that I'm trying to complete.


    upload_2017-9-11_14-36-42.png

    I have some concerns:
    1. Where do I connect the grounds? Grounds for both DC sourcs are different so I can’t connect them both to the same ground as the microcontroller. And by the way, does the MCU have a ground pin? If yes what do I connect to it GRN1, GRN2, GRN3, or all?
    2. I have a doubt about the protection of a 5V microcontroller with the voltage dividers. Are they well sized for both batteries? Specially for DC2, because the voltage in the circuit increases from DC1 to DC2.
    3. Is it possible to take measurements with only one oscillator or do I need a second one?
    4. Is a pic microconntroller suitable for this application? Other propositions?
    5. Any other recommendations?
    Thank you in advance for your help..
     
  2. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,331
    Likes:
    653
    Location:
    Derbyshire, UK
    ONLINE
    You've connected grounds directly across the bottom battery, and have now destroyed it - and possibly burn your home to the ground.

    You can't measure two different voltages like that, the easiest way (with your existing circuit) is to remove GND2 and it's battery connection and connect the bottom of R2 to GND3 - you may also need to increase the value of R1 as well, to give an increased voltage range (10K should be fine).

    A2 will then read the voltage across DC2, and A1 will read the voltage across battery DC2+DC1, so to get the DC1 voltage, subtract the DC2 voltage from the A1 reading.

    The MCU will have at least one GND pin, and they should all be connected to GND3, only the one oscillator is needed, and indeed only one is possible - a PIC would be fine for the project.
     
  3. ronsimpson

    ronsimpson Well-Known Member Most Helpful Member

    Joined:
    Apr 17, 2007
    Messages:
    7,375
    Likes:
    975
    Location:
    Loveland, CO USA
    This picture: all grounds are the same.
    One node is names 12V and another is named 24V.
    To measure the bottom battery you simple read A2, knowing 4V is really 12V.
    To measure the top battery you first read A1, knowing 4V is really 24V. This tells you the voltage of DC1+DC2. Now substrate out DC2.
    upload_2017-9-11_14-38-38.png
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. BM8

    BM8 New Member

    Joined:
    Sep 11, 2017
    Messages:
    3
    Likes:
    0

    Thank you Nigel and ronsimpson for your responses.
    Your solution is understood, but is there any other way to protect the MCU in a standardized manner, because I will eventually have more than 2 batteries on the circuit and it would be perfect to somehow prepare a unique setting for all the batteries regardless of their position on the circuit.
     
    Last edited: Sep 11, 2017
  6. Les Jones

    Les Jones Well-Known Member

    Joined:
    May 15, 2015
    Messages:
    1,474
    Likes:
    191
    Location:
    Lancashire UK
    If you are now planning to use one MCU per battery you could use HC-12 RF modules to transmit the data back to a base station. I use this method. Each sensor module has an HC-12 and the base station has an HC-12. The communication is in the form of serial data. The base sends an address out to select a particular sensor (I use a # character followed by an upper case letter but you could use any addressing system.) The sensor then transmits the data back as an ASCII string of characters.
    This is the schematic of the voltage sensor.
    Monitor_V01.png
    I now use a PIC12F1840. (I used a PIC12F1822 in the first one I built) The potentiometer is to fine tune the calibration

    I also have sensors that also monitor current as well as voltage (Using an INA219) and some that measure temperature and humidity. (Using a DHT22) At the moment I just use a terminal emulator program running on a PC with an HC-12 connected to a serial port. I just type #and a letter and the sensor sends the data as a readable ASCII string of characters. I have been trying to get a Raspberry Pi to read data every few minutes and log it but I am having difficulty at getting the receive code to deal with errors in the transmission. Let me know if you would like a copy of the code that runs on the PIC12F1840

    Les.
     
  7. BM8

    BM8 New Member

    Joined:
    Sep 11, 2017
    Messages:
    3
    Likes:
    0
    Les Jones, thank you for your response. Your solution is very interesting and very close to what I'm trying to achieve. Yes I'm interested in the PIC code please.
    I'm just wondering if in your application the batteries (or DC sources) are in series or in parallel. If in series, how do you protect each module? Do you need to change the resistors for different modules?
    FYI, I edited my last post and removed the schematic with many MCUs because I realized that I was getting off topic, so I concentrated on a single MCU.
     
  8. MikeMl

    MikeMl Well-Known Member Most Helpful Member

    Joined:
    Mar 17, 2009
    Messages:
    11,139
    Likes:
    566
    Location:
    AZ 86334
    Here is a (conceptual) approach where I would start:

    57.png
     
    • Like Like x 1
  9. Les Jones

    Les Jones Well-Known Member

    Joined:
    May 15, 2015
    Messages:
    1,474
    Likes:
    191
    Location:
    Lancashire UK
    Hi BM8,
    I use the voltage monitor (And will be using the voltage and current monitor.) to monitor the voltage of a 12 volt battery for a low voltage lighting system in the garage when it is on charge. It is powered from the battery/charger while on charge so it's "ground" reference is the battery negative.This way you could have one of these sensors connected to any number of batteries in series as it's ground would be referenced to the negative of that 12 volt battery. I use the internal 4.096 volts reference on the PIC so that the input of the ADC reads 0 to 4.096 volts. This means that you hve to have a potential divider on the input to scale the voltage to this range. (The unit that also measures current using the INA219 can only read a maximum voltage of about 27 volts as the current sense resistor is in the positive line so this limit is due to the ratings of the INA219.)
    This is the source code for the PIC12F1840
    Code (text):


    ;   This is for reading voltge from ADC input and transmitting as ASCII string of characters
    ;    Started 19/02/2017
    ;   Modified to disable USART receive after recognising station ID (18/03/17)
    ;******************************************************************************************

    ;

    ;******************************************************************************************
    ;
    ;        OSC      : Internal OSC 4 MHz
    ;
    ;******************************************************************************************
            LIST    P=PIC12F1840,ST=OFF,R=DEC
            INCLUDE  "P12F1840.inc"

            __CONFIG _CONFIG1,  _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF &  _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF


            __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_HI & _LVP_OFF

    ;*******************************************************************************
    ; Constants
    ;*******************************************************************************

    Station_ID   equ   'D'   ;Station identification character for this station  


    RAM_START       equ     0x20


    ; The periods are timed with timer1 which is set to run at the internal clock
    ; rate (4 Mhz) of Fosc/4 or 1.0MHz which is equal to a 1 uS period.




    ;DELAY_6MS   equ   D'2993'    ;Value to give delay of 6 mS
    RX_Timer   equ   D'200'

    ;*******************************************************************************
    ; Pin Assignments
    ;*******************************************************************************
    ;
    ;   PIC signals
    ;
       #DEFINE       TX_Data       PORTA, 0       ;
       #DEFINE       RX_Data       PORTA, 1       ;
    ;
       #DEFINE       AN2       PORTA, 2       ; Analogue input
    ;   #DEFINE       Button       PORTA, 3       ; Push button to trigger  read (Not used)


    ; I/O pin use
    ;   RA0   TX                       (Pin 7)         (To pin 4 on programmer connection)
    ;   RA1   RX               (Pin 6)         (To pin 5 on programmer connection)
    ;   RA2   Analogue input         (Pin 5)
    ;   RA3   Trigger button       (Pin 4)   NOTE THIS PIN CAN ONLY BE USED AS AN INPUT.  
    ;                    (This is VPP for programming This could be connected to pin 3 or 5 of the header to program the chip on header.)
    ;   RA4 (AN3)   Not used         (Pin 3)
    ;   RA5                       (Pin 2)




    ;  Define GENERAL PURPOSE RAM AREA (80 bytes maximum)

    ;*******************************************************************************
    ; File Register Variables
    ;*******************************************************************************
            cblock  RAM_START

    param1:   1          ; parameter 1    (Used in delay cycles routine)
    param2:   1          ; parameter 2    (Used in delay cycles routine)
    Temp_1:   1       ;Used in 2 second delay

    tmpData:   1       ; Used in output_hexbyte routine

    ; delay counters
    Del_Count:     1
           
    ADC_Temp_L:   1
    ADC_Temp_H:   1


    ; byte counter
        bytcnt:     1

    ESEVN:   1       ; 10 000,000 (digit 8)
    ESIX:   1       ; 1000,000s (digit 7 )
    EFIVE:   1       ; 100,000s digit 6 store
    EFOUR:   1       ; 10,000s digit 5 store
    ETHREE:   1       ; 1000s digit 4 store
    ETWO:   1       ; 100s digit 3 store
    EONE:   1       ; 10s digit 2 store
    EZERO:   1       ; 1's digit 1 store



    COUNT:   1

    BCD1:   1       ; overrange
    BCD2:   1       ; MS decimal value
    BCD3:   1       ;
    BCD4:   1       ; decimal value
    BCD5:   1       ; ls decimal value
       
    BIN1:   1       ; LS binary value
    BIN2:   1       ;
    BIN3:   1       ;
    BIN4:   1       ; MS binary value

    TEMP:   1

    RX_Count:   1


            endc
    ;*******************************************************************************
    ; Common RAM (0x70 to 0x7F)
    ;*******************************************************************************

    TX_temp       EQU 0x70       ;Temporary storage for character to be transmitted.
    RX_Temp       EQU 0x71       ;Temporary storage for received character.
    BS_Temp       EQU 0x72       ;Temporary storage for "W" during bank select
    ;*******************************************************************************
    ;  Define Macro     Takes 2 uS
    ;*******************************************************************************
    SELBANK MACRO   #BANK_NO
            MOVLB   #BANK_NO   ;1 cycle - 1 uS  
            ENDM


    ; *****************************

            ORG     0h
            GOTO    START
            ORG     4h
            GOTO    START
    START
    ; *****************************
    ;   Initialized Segment
    ; *****************************
    ; Initialise OSC (4MHz, IntOSC)
            SELBANK 1               ; SET BANK1
            MOVLW   B'11101010'      
            MOVWF   OSCCON

       BCF   INTCON,GIE

    ; Initialise I/O port
            SELBANK 1               ; SET BANK1
            MOVLW   B'00001110'       ; Bits 0, 4, 5 output Bit 1, 2,  3 input.
            MOVWF   TRISA

    ;Set pullup on PORTA,3

       BCF   OPTION_REG,NOT_WPUEN

               SELBANK 4               ; SET BANK 4
       MOVLW   B'00001000'
       MOVWF   WPUA

               SELBANK 3               ; SET BANK 3
       MOVLW   B'00000100'
       MOVWF   ANSELA       ; Set bit 2 as analogue, set the rest to digital

             SELBANK 2               ; SET BANK2

    ; Initialized Comparitor.
               MOVLW   B'00000000'       ; Comparator disabled.
       MOVWF   CM1CON0           ;In bank 2
               SELBANK 0               ; SET BANK0

       CLRF   PORTA       ;Set all outputs low



    ; Initialized EUSART
               SELBANK 3               ; SET BANK 3
       MOVLW   B'00000000'
       MOVWF   BAUDCON

       BSF   TXSTA,BRGH   ; Set baud rate high bit
           BSF     TXSTA,TXEN    ;enable transmission  

       MOVLW   0x19       ; Decimal 25 for 9600 baud rate
       MOVWF   SPBRGL
       MOVLW   0x00
       MOVWF   SPBRGH

         BSF     RCSTA,SPEN    ;enable serial port
       BSF     RCSTA,CREN    ;enable receive

             SELBANK 0               ; SET BANK0

    ; Initialized Timer 1
             SELBANK 0               ; SET BANK0

       MOVLW   B'00010100'   ;Clock source FOSC, 1:2 prescale, Dedicated Timer1 oscillator circuit disabled,
                                    ;Do not synchronize external clock input, Timer off

       MOVWF   T1CON       ;With 4 Mhz clock timer will increment every 500 nS

       MOVLW   0x00       ;All bits clear (Gate control not used.)
       MOVWF   T1GCON

    ; Initialized ADC

             SELBANK 1               ; SET BANK1
       MOVLW   0x09       ; Channel 2, ADON (Bit 0)
       MOVWF   ADCON0

       MOVLW   B'11010011'   ; Bit 7 Result right justified. ADCS 101 /16 (Bits 6 & 4 set ).  ADPREF bits 0 & 1 set (FVR module.)
       MOVWF   ADCON1

             SELBANK 2               ; SET BANK2
       MOVLW   B'10000011'   ;Bit 7 enable. Bits 0,1 4.096V ref
       MOVWF   FVRCON

             SELBANK 0               ; SET BANK0

    ; *****************************
    ;   Program main
    ; *****************************
    ; Main loop

    ;   CALL Delay_2_Sec

    MAIN:

    Wait_Rx_Chr:           ;Wait for a received character

       SELBANK 3
       BSF     RCSTA,CREN    ;enable receive
       SELBANK 0

       bcf   PORTA,5       ;   TEST switch off LED
       BCF   PORTA,4           ;TEST switch off LED
       CALL   SerialReceive
    ;   CALL    SerialTransmit ;Echo character as a test
    ;   MOVF   RX_Temp,W
    ;   BCF   PORTA,5           ;TEST switch off LED

       XORLW   '#'       ;Wait for # character.
       BTFSS   STATUS,Z
       GOTO   Wait_Rx_Chr   ; Not # character

       MOVLW   RX_Timer   ; Number of 10 mS to wait for station ID character
       MOVWF   RX_Count


    Test_DAV:
           btfsc   PIR1,RCIF    ;check if data received
       GOTO   Read_Data
       CALL   Delay_10mS
       DECFSZ   RX_Count
       GOTO   Test_DAV
       GOTO   Wait_Rx_Chr



    Read_Data:
    ;   bsf   PORTA, 4       ; led ON  test ONLY

         SELBANK 3               ; SET BANK 3
           movf    RCREG,W           ;get received data into W
       BCF     RCSTA,CREN       ;disable receive
    ;   MOVWF   RX_Temp
           SELBANK 0               ; SET BANK 0
    ;   MOVF   RX_Temp,W
    ;   CALL    SerialTransmit ;Echo character as a test
       XORLW   Station_ID
       BTFSS   STATUS,Z
       GOTO   Wait_Rx_Chr   ; Not this station

       CALL   Read_ADC

       CALL   Output_Decimal       ;Output in decimal

       MOVLW   0x0D       ;C/R
       CALL   SerialTransmit

       MOVLW   0x0A       ;L/F
       CALL   SerialTransmit

    ;   CALL Delay_2_Sec
       CALL Delay_100mS
       CALL Delay_100mS
       CALL Delay_100mS

       GOTO   Wait_Rx_Chr
    ;       --------------------------------------------------------------------------------------


    ; *****************************
    ;   Subroutines
    ; *****************************
                       
    ;*****************************************************************************      
    ;
    ;   Function :  SerialTransmit
    ;               This function sends the byte in W over the RS232 port. The
    ;               function will wait until previous data has been sent
    ;
    ;   Input:      Byte in W
    ;
    ;   Output:    
    ;
    ;*****************************************************************************      
    SerialTransmit:
    ;   MOVWF   TX_temp
           btfss   PIR1,TXIF    ;check that buffer is empty
           goto    $-1
           SELBANK 3               ; SET BANK 3
    ;   MOVF   TX_temp,W  
           movwf   TXREG        ;transmit byte
           SELBANK 0               ; SET BANK 0
           return
    ;*****************************************************************************
         
    SerialReceive:

    ;Start of test code
    ;   CALL   Toggle_bit5

    ;    SELBANK 3               ; SET BANK 3
    ;   BTFSC   RCSTA,1       ;test for OVERRUN error
    ;   BSF   PORTA,4
    ;       SELBANK 0               ; SET BANK 0
    ;End of test code

           btfss   PIR1,RCIF    ;check if data received
           goto    SerialReceive           ;wait until new data
         SELBANK 3               ; SET BANK 3
           movf    RCREG,W        ;get received data into W
    ;   MOVWF   RX_Temp
           SELBANK 0               ; SET BANK 0
    ;   MOVF   RX_Temp,W
           return
    ;*****************************************************************************  
           
    ;*Read ADC
    ;* Result in ADC_TempL & ADC_Temp_H
    ;*
    ;*****************************************************************************  
    ;
         
    Read_ADC:
             SELBANK 1               ; SET BANK 1
       MOVLW   0x09       ; Channel 2, ADON (Bit 0)
       MOVWF   ADCON0
       
       NOP       ;For short delay
       NOP
       NOP
       NOP
       NOP

       BSF   ADCON0,ADGO   ;Start conversion
    ADC_Tst:  
       BTFSC   ADCON0,ADGO  
       GOTO   ADC_Tst
       MOVFW   ADRESH
           SELBANK 0               ; SET BANK 0
       MOVWF   ADC_Temp_H
             SELBANK 1               ; SET BANK 1
       MOVFW   ADRESL
           SELBANK 0               ; SET BANK 0
       MOVWF   ADC_Temp_L



    ; Rotate left 4 bits
       RLF   ADC_Temp_L
       RLF   ADC_Temp_H
       RLF   ADC_Temp_L
       RLF   ADC_Temp_H
       RLF   ADC_Temp_L
       RLF   ADC_Temp_H
       RLF   ADC_Temp_L
       RLF   ADC_Temp_H
       MOVLW   0xF0
       ANDWF   ADC_Temp_L   ; Clear bits 0 to 3 that could have been set by uncleared carry bit
       RETURN

    ;       -----------------------------------------------------------------------------



    Delay_10mS:           ;Need to set param to (10000 - 14)/2  = 9986/2 = 4993 = 0x1381
       MOVLW   0x13
       MOVWF   param2
       MOVLW   0x81
       MOVWF   param1
       GOTO   delay_cycles




    Delay_100mS:
       MOVLW   0xC3
       MOVWF   param2
       MOVLW   0x49
       MOVWF   param1
       GOTO   delay_cycles
       
    Delay_2_Sec:
       MOVLW   D'20'
       MOVWF   Temp_1
    D2_Loop:
       CALL   Delay_100mS
       DECFSZ   Temp_1
       GOTO   D2_Loop
       RETURN

    ;*******************************************************************************
    ; Function:    delay_cycles
    ; Description: Delay a specified number of instruction cycles including
    ;              interrupt cycles.  The function call overhead adds between
    ;              13 and 16 cycles of delay on top of the specified value.
    ; With 4 Mhz system clock and 1:2 prescale
    ;Delay will be  param * 2 uS + (13 * 1uS)  + 0 to 3 uS
    ;       = param * 2 uS + (13 to16.0 uS)  (Use 14 uS for calculation.)
    ;   So param = No. of uS/2 - 7
    ; Parameters:  param1 - least significant byte of 16 bit cycle delay
    ;              param2 - most significant byte of 16 bit cycle delay
    ; Returns:     None
    ;*******************************************************************************
    delay_cycles:
            comf    param1,F                ; negate the delay by complementing the       (1 uS)           (1 cycle)
            comf    param2,F                ; low and high bytes               (1 uS)           (1 cycle)
            bcf     T1CON,TMR1ON            ; stop timer 1                   (1 uS)           (1 cycle)
            movf    param1,W                ; move the low byte of the delay into       (1 uS)           (1 cycle)
            movwf   TMR1L                   ; timer 1                   (1 uS)           (1 cycle)
            movf    param2,W                ; move the high byte of the delay into       (1 uS)           (1 cycle)
            movwf   TMR1H                   ; timer 1                   (1 uS)           (1 cycle)
            bcf     PIR1,TMR1IF             ; clear the timer 1 rollover flag       (1 uS)           (1 cycle)
            bsf     T1CON,TMR1ON            ; turn on timer 1               (1 uS)           (1 cycle)
           
    tmr1_check:    
            btfss   PIR1,TMR1IF             ; wait for the timer 1 rollover flag to       1 uS while looping    (2 uS) (2 cycle) on exit
            goto    tmr1_check              ; trigger
            return               ;                       (2 uS)   (2 cycle)

    ;**********************************************************************************
    ; Subroutine BCD (to convert 28-bit binary to 8-digit BCD)
    ; Binary value is in BIN1, BIN2, BIN3 & BIN4. BIN1 is LSB, BIN4 is MSB
    ; Result in BCD is in BCD1, BCD2, BCD3, BCD4 & BCD5. BCD1 is for overrange,
    ; BCD2 is MSB, BCD5 is LSB
    ;**********************************************************************************

    BIN_BCD:  
       bcf   STATUS,C   ; clear carry bit
       movlw   D'32'
       movwf   COUNT       ; 32 in count
       clrf   BCD1       ; set BCD registers to 0
       clrf   BCD2
       clrf   BCD3
       clrf   BCD4
       clrf   BCD5

    LOOPBCD:
       rlf   BIN1,f       ; LSB shift left binary registers
       rlf   BIN2,f
       rlf    BIN3,f
       rlf   BIN4,f       ; MSB
       rlf   BCD5,f       ; LSB shift left BCD registers
       rlf   BCD4,f
       rlf   BCD3,f
       rlf   BCD2,f
       rlf   BCD1,f       ; MSB

       decfsz   COUNT,f       ; reduce count value return when 0
       goto   DECADJ       ; continue decimal adjust
       
    ; result in BCD1-5. (BCD1 overrange, BCD2 MS byte)

       swapf   BCD2,w       ; get ms nibble
       andlw   0x0F
       iorlw   0x30       ; convert to ASCII
       movwf   ESEVN       ; ms digit
       movf   BCD2,w       ; get 2nd ms nibble
       andlw   0x0F
       iorlw   0x30       ; convert to ASCII
       movwf   ESIX

       swapf   BCD3,w       ; get next nibble
       andlw   0x0F
       iorlw   0x30       ; convert to ASCII
       movwf   EFIVE       ; ms digit
       movf   BCD3,w       ; get next nibble
       andlw   0x0F
       iorlw   0x30       ; convert to ASCII
       movwf   EFOUR
       
       swapf   BCD4,w       ; get ms nibble
       andlw   0x0F
       iorlw   0x30       ; convert to ASCII
       movwf   ETHREE       ; ms digit
       movf   BCD4,w       ; get 2nd ms nibble
       andlw   0x0F
       iorlw   0x30       ; convert to ASCII
       movwf   ETWO

       swapf   BCD5,w       ; get ms nibble
       andlw   0x0F
       iorlw   0x30       ; convert to ASCII
       movwf   EONE       ; ms digit
       movf   BCD5,w       ; get 2nd ms nibble
       andlw   0x0F
       iorlw   0x30       ; convert to ASCII
       movwf   EZERO
       return           ; completed decimal to BCD operation

    ; subroutine decimal adjust

    DECADJ   movlw   BCD5       ; BCD LSB address
       movwf   FSR1L       ; pointer for BCD5
       CLRF   FSR1H
       call   ADJBCD       ; subroutine to adjust BCD
       movlw   BCD4
       movwf   FSR1L
       CLRF   FSR1H
       call    ADJBCD
       movlw   BCD3
       movwf   FSR1L
       CLRF   FSR1H
       call    ADJBCD
       movlw   BCD2
       movwf   FSR1L
       CLRF   FSR1H
       call    ADJBCD
       movlw   BCD1
       movwf   FSR1L
       CLRF   FSR1H
       call    ADJBCD
       goto   LOOPBCD

    ; subroutine adjust BCD

    ADJBCD   movlw   0x03       ; w has 03
       addwf   INDF1,w       ; add 03 to BCDx register (x is 1-5)
       movwf   TEMP       ; store w
       btfsc   TEMP,3       ; test if >7
       movwf   INDF1       ; save as LS digit
       movlw   0x30       ; 3 for MSbyte
       addwf   INDF1,w       ; add 30 to BCDx register
       movwf   TEMP       ; store w
       btfsc   TEMP,7       ; test if >7
       movwf   INDF1       ; save as MS digit
       return           ; end subroutine



    ;**********************************************************************************
    ;
    ;
    Output_Decimal:

       CLRF   BIN4       ;Clear top 3 bytes (Not used.)
       CLRF   BIN3
       CLRF   BIN2
       
       MOVF   ADC_Temp_H,W   ;ADC high byte
       MOVWF   BIN2  

       MOVF   ADC_Temp_L,W   ;ADC low byte
       MOVWF   BIN1  

       CALL   BIN_BCD

    Output_Reading:

       MOVF   EFOUR, W
           CALL    SerialTransmit  

       MOVF   ETHREE, W
           CALL    SerialTransmit  

       MOVLW   '.'
           CALL    SerialTransmit

       MOVF   ETWO, W
           CALL    SerialTransmit

       MOVF   EONE, W
           CALL    SerialTransmit


       MOVF   EZERO, W
           CALL    SerialTransmit


       MOVLW   ' '
           CALL    SerialTransmit



       MOVLW   'V'
           CALL    SerialTransmit
       MOVLW   'o'
           CALL    SerialTransmit
       MOVLW   'l'
           CALL    SerialTransmit
       MOVLW   't'
           CALL    SerialTransmit
       MOVLW   's'
           CALL    SerialTransmit
       MOVLW   ' '
           CALL    SerialTransmit



       RETURN


    ;Toggle_bit5:           ;Used for testing
    ;   MOVWF BS_Temp
    ;   MOVLW   b'00100000'
    ;   XORWF   PORTA,f       ;Toggle bit 5
    ;   MOVFW   BS_Temp
    ;   RETURN


       end



     
    The station identification letter is the first entry in the list of constants.
    You will have to make sure that none of the ststions send a message back to the master that could contain text that could be seen by another station and interpreted as it's station address.
    The code could be tidied up by using RETLW instructions so the text messages could be in a table. Note there ar still some bits of code that I used for testing that are commented out. Let me know if you would like the code for the sensors using the INA219 and the DHT22.

    Les.
     

Share This Page