Hi Guys, Thanks for the tips, it did got me thinking about this. I needed something to get me of the cycle I was in... Is the same old problem of trying to write software for maximum flexibility which gets completely out of control= .. The problem here is how to deal with the sensor which is a individual entity that actually in real terms gets data from a peripheral that as several inputs that in a way are all linked. I wanted to leave on the fly configuration out of it for the moment just to get me going, hence I need to decide what to do for configuration. do I setup all channels to sample and pickup the ones I need or do I just setup the channels I need at the moment and change configuration as required for each program. I also need to look at packet size. Using the way I construct my packets back to the controller, if I get all the channels values back, I will have 225 bytes which to me seems quite a lot for a single packet. Both of you have the same concept of commands or requests to the modules, but you use different methods, I am working on that the moment. I would like the sensors to be single entity that I could request from the module as a single value, but also would like to be able to request a number of sensors in one request, and have the module use the least time to do it. I am probably over-thinking it... I am implementing the ADC module with all channels being read and stored it on the buffer, as I think that is a good starting point. I am also implementing the sensor in a similar fashion as Chris, I just then need to implement the commands. I will start by getting all the values and work from there. Thanks. Luis On 14 January 2013 23:56, IVP wrote: > > Sorry if I sounded dismissive of your post, it wasn't my intention > > No worries > > > lets say that I have five analogue sensors connected to the same > > ADC but different channels, how do you handle that? > > Because each module has at least one PIC, there are more than enough > ADC i/p, so you'd cycle them with the adcon register. My system is on > a general 1Hz tick so sampling speed is not an issue. I can either let th= e > probes sample on every tick or interrogate them remotely on demand. > I do have a buffer system as your friend suggested. The sampling frequenc= y > and buffer size are user-definable. For many applications the voltage > being measured does not change very quickly, eg ambient temperature > or the sensor itself doen't react very quickly > > Additionally, the core generates a 10ms tick. This is received by all > sensors/modules and is used, together with the numeric value of their > addresses, to separate communication packets. So for example, and > very basically, if a module has information to send, it counts the number > of 10ms ticks it receives after the 1Hz tick, and when that count equals > its assigned address (based on when it was detected on power-up), it > transmits > > > I want to make the sensor an individual entity but the five sensors are > > really five ADC channels which are part of the same ADC > > In my case an individual sensor is selected with a text string. Here's a > partial list of analogue commands. There is a higher set to address a > particular module. For example AN01 to AN04 are one module, AN05 > to AN08 are another and so on, so the core does a /4 to find which > module the required ADC is on. All strings are terminated with ^ > > ; ANA read all > ; ANC cancel all AN commands > ; AN## C cancel AN## command > ; AN## S vvvvv set scale of AN## > ; AN## read AN## > ; ANA mmm read all every mmm > ; AN## mmm read AN## every mmm > ; AN## tttt read AN## at tttt each day > ; ANA tttt read all at tttt each day > ; AN## R mmm record AN## every mmm > ; ANA R mmm record all every mmm > ; AN## Gvvv [mmm] read AN## [every mmm], alert if AN## = > > vvv > ; AN## Lvvv [mmm] read AN## [every mmm], alert if AN## = < > vvv > ; AN## Evvv [mmm] read AN## [every mmm], alert if AN## = =3D > vvv > ; AN## [G][L][E]vvv [mmm] [W][P] send every mmm to web, alert to phone > > The ## in AN## is detected and evaluated as below. You'll appreciate > there are many hundreds of lines of code to cover all the commands. To > relieve the core (an 18F4550) of a lot of donkey work, each module > controller (an 18F1320) has its own copy of what could be described as > an interpreter. Some alterations are made to suit the module - AN for > analogue, RY for relay, IO for digital, HV, LV for high and low voltage > (which also have commands for switching input dividers) and so on > > Once a value has been got by the ADC, it's converted to a text string > and compiled, along with an echo of the command, phone number and/ > or email address etc, time stamp, then transmitted to the core, which in > turn sends it to a cellular modem. For other modules a pin status might > be found, rather than a voltage. Such as a relay on/off or an input L/H > > Hope that helps. It sounds complicated but actually, as with all s/w, it'= s > just a management plan and a collection of very small jobs > > Joe > > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > > tst_ac lfsr fsr0,r_byte+.2 ;input string source, skip AN > > movf indf0,w > xorlw "A" ;test for ANA (measure all) > skpnz ;no > goto msr_all ;yes > > movf indf0,w > xorlw "C" ;test for ANC (cancel all) > skpnz ;no > goto cncl_all ;yes > > ;next two characters must be device number > > movf postinc0,w > andlw 0x0f ;reduce device ## to one hex byte > movwf temp0 > > clrc ; ## x 10 =3D x 2 + x 8 > rlcf temp0,w > movwf dev_no > rlcf temp0 > rlcf temp0 > rlcf temp0,w > addwf dev_no > > movf postinc0,w > andlw 0x0f ; + units > addwf dev_no ;dev_no =3D device number, 1-4 > > movf postinc0,w > xorlw "^" ;test for AN##^ > skpz ;yes > bra tst_let ;no, test for letter > > call msr_one ;get value > call mul16x8 ;convert ADC to string > goto message ;compose message and send > ;exits to wait_ser > > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > ; Measure one AN > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > msr_one movf dev_no,w ;select AN channel > xorlw .1 > bnz anch2 > > bcf adcon0,chs0 > bcf adcon0,chs1 > bcf adcon0,chs2 > goto sample > > anch2 movf dev_no,w > xorlw .2 > bnz anch3 > > bsf adcon0,chs0 > bcf adcon0,chs1 > bcf adcon0,chs2 > goto sample > > anch3 movf dev_no,w > xorlw .3 > bnz anch4 > > bcf adcon0,chs0 > bsf adcon0,chs1 > bcf adcon0,chs2 > goto sample > > anch4 bsf adcon0,chs0 > bsf adcon0,chs1 > bcf adcon0,chs2 > goto sample > > sample bsf adcon0,go_done ;start conversion > nop > btfsc adcon0,go_done > bra $-2 > > ;transfer result > > movf adresl,w > movwf temp4 > movf adresh,w > movwf temp3 > return > > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > ; Convert ADC to user units > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > ;(ADC * resolution)/1000 > > ; temp3:4 (MSB:LSB) =3D ADC - 10-bit > ; temp5 =3D resolution - 8-bit > ; temp0:1:2(MSB:LSB) =3D 24-bit product > ; temp6 =3D bitcount > > ;Multiply ADC reading * resolution > > mul16x8 clrf temp0 ;clear result area > clrf temp1 > clrf temp2 > > mov 0x01,temp3 > mov 0xb8,temp4 > > ; lfsr fsr0,reso1 ;get resolution of device > ; > ; decf dev_no,w > ; addwf fsr0l > ; > ; movlw low(indf0) ;1 bit of ADC =3D xx units > ; movwf temp5 > > mov .5,temp5 > clrf temp7 > > ;http://www.piclist.com/techref/microchip/math/mul/16x16bfsd.htm > ; n_2 : n_1 * n_4 : n_3 -> q_4:q_3:q_2:q_1 > ; temp3:temp4 * temp7:temp5 -> temp8:temp0:temp1:temp2 > > clrf temp8 ;not needed in result > clrf temp0 > clrf temp1 > clrf temp2 > bsf temp1,7 > > m1 rrcf temp3 > rrcf temp4 > skpc > bra m2 > movf temp5,w > addwf temp0 > movf temp7,w > skpnc > incfsz temp7,w > addwf temp8 > > m2 rrcf temp8 > rrcf temp0 > rrcf temp1 > rrcf temp2 > skpc > bra m1 > > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > ; Find digits > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > ; Dividend - temp0:temp1:temp2 (MSB:NSB:LSB) =3D (ADC * resolution) > ; Divisor - temp3:temp4 (MSB:LSB) =3D 1,000 (03E8) > ; Bit counter - temp8 > ; Remainder - tmp_valh:tmp_vall > ; Quotient - temp5:temp6:temp7 > > div2416 clrf tmp_vall ;clear remainder > clrf tmp_valh > > ok2div movlw 0x03 > movwf temp3 ;set divisor =3D 1,000 > movlw 0xe8 > movwf temp4 > movlw .24 > movwf temp8 ;bit count > > lpu2416 rlcf temp2 ;shift left divider to pass next bit to > remainder > rlcf temp1 ;and shift in next bit of result > rlcf temp0 > > rlcf tmp_vall ;shift carry into remainder > rlcf tmp_valh > > rlcf temp8 ;save carry in counter > > movf temp4,w ;subtract divisor from remainder > subwf tmp_vall > movf temp3,w > skpc > incfsz temp3,w > subwf tmp_valh,w ;keep byte in W until borrow tested > > skpnc ;if no borrow > bsf temp8,0 ;set bit 0 of counter (saved carry) > > btfsc temp8,0 ;if no borrow > goto uok46ll ;else > > movf temp4,w ;restore remainder if borrow > addwf tmp_vall > movf tmp_valh,w ;read high byte of remainder to W > ;to not change it by next instruction > > uok46ll movwf tmp_valh ;store high byte of remainder > clrc ;copy bit 0 to carry > rrcf temp8 ;and restore counter > decfsz temp8 ;decrement counter > goto lpu2416 > > ; clrc > rlcf temp2 ;shift in last bit of result > rlcf temp1 > rlcf temp0 > > ; movf temp1,w ;1000s in hi:lo > ; movwf tmp_valh > ; movfw temp2 > ; movwf tmp_vall > > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > ; Make ASCII number string for message > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > ; Convert 8-bit data to 3-digit ASCII > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > ;data (1000s) to convert is in temp2 > > bin2bcd ;movlw .13 > ;movwf temp2 > ;movlw low(.500) > ;movwf tmp_vall > ;movlw high(.500) > ;movwf tmp_valh > movlw .1 > movwf dev_no > > clrf temp5 > swapf temp2,w > addwf temp2,w > > andlw b'00001111' > > btfsc dc > addlw 0x16 > btfsc dc > addlw 0x06 > addlw 0x06 > btfss dc > addlw -0x06 > btfsc temp2,4 > addlw 0x16 - 1 + 0x6 > btfss dc > addlw -0x06 > btfsc temp2,5 > addlw 0x30 > btfsc temp2,6 > addlw 0x60 > btfsc temp2,7 > addlw 0x20 > addlw 0x60 > rlcf temp5 > btfss temp5,w > addlw -0x60 > movwf temp7 > btfsc temp2,7 > incf temp5 > movf temp5,w > addlw 0x30 > movwf temp5 > > swapf temp7,w ;separate 10s > andlw 0x0f > addlw 0x30 ;convert to ASCII > movwf temp6 > > movlw 0x0f ;separate 1s > andwf temp7,w > addlw 0x30 ;convert to ASCII > movwf temp7 > > ;copy to message string area > clrf string2+3 > clrf string2+4 > > movf temp5,w > movwf string2+0 > movf temp6,w > movwf string2+1 > movf temp7,w > movwf string2+2 > > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > ; Convert 16-bit data to 5-digit ASCII > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > ;data (100 10 1) to convert is in tmp_valh:tmp_vall > > ascii16 nop > > radix dec ;base 10 > > clrf ab4dp ;known zero > clrf temp0 > > movlw string3 > movwf fsr0l > > goto skpinc1 > sub10k incf temp0 > skpinc1 movlw 10000 & 255 > subwf tmp_vall > > IFNDEF kzero > > movlw 10000 >> 8 > skpc > movlw (10000>>8)+1 > subwf tmp_valh > ELSE > rlcf ab4dp,w > sublw (10000>>8)+1 > subwf tmp_valh > ENDIF > bc sub10k > call out_temp > > movlw 10 > movwf temp0 > add1K decf temp0 > movlw 1000 & 255 > addwf tmp_vall > > IFNDEF kzero > movlw 1000 >> 8 > skpnc > movlw (1000>>8)+1 > addwf tmp_valh > ELSE > rlcf ab4dp,w > addlw 1000 >> 8 > addwf tmp_valh > ENDIF > bnc add1k > call out_temp > > clrf temp0 > movlw 100 > goto skpinc2 > sub100 > incf temp0 > skpinc2 subwf tmp_vall > skpnc > goto sub100 > > decf tmp_valh > btfss tmp_valh,7 > goto sub100 > > call out_temp > > movlw 10 > movwf temp0 > add10a decf temp0 > addwf tmp_vall > bnc add10a > call out_temp ;convert and store > call out_lo ;convert and store > > radix hex > > goto combine ;add two strings together for message > > ;convert to ASCII and store > > out_temp movf temp0,w > addlw 0x30 ;add 0x30 to convert to ASCII > movwf indf0 > incf fsr0l ;store in RAM > return > > out_lo movf tmp_vall,w > addlw 0x30 > movwf indf0 > return > > ;=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > > -- > http://www.piclist.com PIC/SX FAQ & list archive > View/change your membership options at > http://mailman.mit.edu/mailman/listinfo/piclist > -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .