Hey Dave,
I don't know if I can help, but my project is basically doing that now... I think the more experienced gurus on the forum are going to request your code so far. Post that, and you'll have tons of help.
Chris
Hey Dave,
I don't know if I can help, but my project is basically doing that now... I think the more experienced gurus on the forum are going to request your code so far. Post that, and you'll have tons of help.
Chris
Here is my code, feel free to offer suggestions or modifications.
Code:' Read and write hardware USART B1 var byte Done var byte TxBuf var byte[3] STX var byte ETX var byte Period var byte i var byte tmpval var byte ' Initialize USART TRISC = %10111111 ' Set TX (PortC.6) to out, rest in SPBRG = 25 ' Set baud rate to 2400 RCSTA = %10010000 ' Enable serial port and continuous receive TXSTA = %00100000 ' Enable transmit and asynchronous mode ' Define ADCIN parameters Define ADC_BITS 10 ' Set number of bits in result Define ADC_CLOCK 3 ' Set clock source (3=rc) Define ADC_SAMPLEUS 50 ' Set sampling time in uS adval var word ' Create adval to store result TRISA = %11111111 ' Set PORTA to all input ADCON1 = %10000010 ' Set PORTA analog and right justify result Pause 500 ' Wait .5 second ' Echo received characters in infinite loop STX = 2 ETX = 3 Period = 46 TxBuf[1] = 51 TxBuf[2] = 54 TxBuf[3] = 56 mainloop: ADCIN 0, adval ' Read channel 0 to adval 'basicaly here i want to convert advar into 3 ascii numbers 'representing advar 'So a result like 936 would put '57 in txbuf[1] '51 in txbuf[2] '54 in txbuf[3] 'Then call the serial output routine which adds a stx char, 2 digits 'a period then the last digit followed by an ETX char Gosub StringOut ' Send character to serial output pause 500 ' Wait half second Goto mainloop ' Do it forever ' Subroutine to get a character from USART receiver charin: B1 = 0 ' Preset to no character received If PIR1.5 = 1 Then ' If receive flag then... B1 = RCREG ' ...get received character to B1 Endif ciret: Return ' Go back to caller ' Subroutine to send a character to USART transmitter charout: If PIR1.4 = 0 Then charout ' Wait for transmit register empty TXREG = B1 ' Send character to transmit register done = 1 Return ' Go back to caller ' Subroutine to send a character string to USART transmitter 'First Send STX (02) then 2 digits, then period (46), then 1 digit, then ETX (03) StringOut: If PIR1.4 = 0 Then StringOut ' Wait for transmit register empty done = 1 TXREG = STX ' Send character to transmit register while PIR1.4 = 0 wend for i = 1 to 2 TXREG = TxBuf[i] ' Send character to transmit register while PIR1.4 = 0 wend next i TXREG = Period ' Send character to transmit register while PIR1.4 = 0 wend TXREG = TxBuf[3] ' Send character to transmit register while PIR1.4 = 0 wend TXREG = ETX ' Send character to transmit register while PIR1.4 = 0 wend Return ' Go back to caller
Last edited by ScaleRobotics; - 24th July 2010 at 04:22. Reason: added code tags
Put your code in code tags and post it. Not going to risk or take the time to download and open a ZIP when a ZIP is not needed.
This chip only has a 10 bit resolution so you need to explain what you are after. The ADC result can be sent serially with out an array of ant type...put the result in a 4 byte array
Here is a sample to read the ADC at an 8 bit resolution. Maybe it will get you started.
Code:ADCON1 = %00001110 OUT_TEMP VAR BYTE MAIN_LOOP: GOSUB GET_AD GOTO MAIN_LOOP GET_AD: ADCON0=00000001 GOSUB READ_AD OUT_TEMP = ADRESH RETURN READ_AD: PAUSE 50 ADCON0.2=1 WHILE ADCON0.2=1:WEND RETURN
Dave
Always wear safety glasses while programming.
Code:txbuf[1] = advar / 1000 txbuf[2] = (advar - txbuf[1] * 1000) /100 txbuf[3] = (advar-((txbuf[1] * 1000) + (txbuf[2] * 100)))/10 txbuf[4] = advar - ((txbuf[1] * 1000) + (txbuf[2] * 100)+ txbuf[3] * 10)
Dave
Always wear safety glasses while programming.
Dave, with referece to your code please note that when you declare an array, the number you state is the real number of elements of your array. you stated 3 elements, so you will have the following bytes available:
TxBuf var byte[3]
'basicaly here i want to convert advar into 3 ascii numbers
'representing advar
'So a result like 936 would put
'57 in txbuf[1]
'51 in txbuf[2]
'54 in txbuf[3]
'Then call the serial output routine which adds a stx char, 2 digits
'a period then the last digit followed by an ETX char
txbuf[0]
txbuf[1]
txbuf[2]
Now since you are decoding a 10bits adc then the maximum reading you can obtain in adval is 1023, which are four digits so you will need a 4 bytes array for your data transfer.
Hence, you have to declare:
txbuf var byte [4]
and you will have the following bytes available:
txbuf[0]
txbuf[1]
txbuf[2]
txbuf[3]
Please read page 33 of PBP manual, you will find the DIG instruction that could help you in moving the single digits into your array. Here a snippet as an example:
Al.Code:A var byte ' used for the FOR/NEXT loop For A=0 to 3 txbuf[A]= adval DIG A next A 'assuming adval contains the value 1023 then your array will end up as follows: 'txbuf[0]="3" 'txbuf[1]="2" 'txbuf[2]="0" 'txbuf[3]="1" In case you want them the other way then For A=0 to 3 txbuf[A]= adval DIG (3-A) next A 'will yield: 'txbuf[0]="1" 'txbuf[1]="0" 'txbuf[2]="2" 'txbuf[3]="3"
Last edited by aratti; - 24th July 2010 at 16:05.
All progress began with an idea
Thanks Everyone for the input! I'm now able to read values from my sensor. I now have 2 additional questions.
1. Is there a better way to send serial; data than the way I'm doing it? Anyone have a routine that they think works better?
2. It seems like my returned values vary quite a bit. I don't have access to a scope, but it seems that the sensor is returning pretty constant voltage. it returns 0 - 10 v I am using a voltage divider made up of 2 2.2 K resistors to shift the sensor output to 0 - 5 volts. Any hints on making the system more stable? Slow down the conversion time? My requirements are pretty easy, i need to read the sensor no more than twice a second.
Thanks again for everyone's help!
Dave
Yes, use HSEROUT.1. Is there a better way to send serial; data than the way I'm doing it? Anyone have a routine that they think works better?
HSEROUT[STR txbuf \ 4] , will send your array out at the baud rate choosen in your define.
See page 79 - 80 of PBP manual.
Read the thread at the given link, you will find the technique and snippets to keep your adc reading stable.2. It seems like my returned values vary quite a bit. I don't have access to a scope, but it seems that the sensor is returning pretty constant voltage. it returns 0 - 10 v I am using a voltage divider made up of 2 2.2 K resistors to shift the sensor output to 0 - 5 volts. Any hints on making the system more stable? Slow down the conversion time? My requirements are pretty easy, i need to read the sensor no more than twice a second.
www.picbasic.co.uk/forum/showthread.php?t=6734
Al.
Last edited by aratti; - 25th July 2010 at 10:00.
All progress began with an idea
For certain, Al's method is the preferred way if you are going to send ascii. However, in most situations you can send the actual data instead of the ascii representation of it. Doing so makes it MUCH faster and MUCH smaller code, because you are sending half the data and doing do it without ascii conversions.
Instead of
dim TxBuf[4] as byte 'var declaration
HSEROUT[STR txbuf \ 4] 'sending data
dim TxBuf as word 'new var declaration
HSEROUT[TxBuf] 'new sending data
now your pic will send two bytes, low byte first.
Side Note: As a personal preference, I like to make the first letter of a variable the first letter of the type. So I would make it wTxBuf, since it is a word. This makes it a lot easier to find type mismatch errors.
Want to thank everyone for their help on this! I'm posting my code as of right now for review and comments.
Al, Even with the multiple collections, sorting and averaging routines put in, I'm still getting a wider variance of data than I think I should ]. Do I have the code right? If so, could my voltage divider be the wrong value?
Also, I tried to increase the baudrate to 9600 and it seemed to stop transmitting, does my serial setup code look OK? I am using a 4 mhz crystal.
Thanks again Everyone!
Dave
Code:' Read and write hardware USART B1 var byte Done var byte TxBuf var byte[3] SendBuf var byte[6] STX var byte ETX var byte Period var byte i var byte tmpval var byte A var byte 'for for next loop DatAvg var word CounterA var Word DataA var Word RawData var Word [16] ' Initialize USART TRISC = %10111111 ' Set TX (PortC.6) to out, rest in ' Set receive register to receiver enabled DEFINE HSER_RCSTA 90h ' Set transmit register to transmitter enabled DEFINE HSER_TXSTA 20h ' Set baud rate DEFINE HSER_BAUD 2400 DEFINE HSER_SPBRG 25 'Hser spbrg init ' Define ADCIN parameters Define ADC_BITS 10 ' Set number of bits in result Define ADC_CLOCK 3 ' Set clock source (3=rc) Define ADC_SAMPLEUS 50 ' Set sampling time in uS adval var word ' Create adval to store result TRISA = %11111111 ' Set PORTA to all input ADCON1 = %10000010 ' Set PORTA analog and right justify result Pause 500 ' Wait .5 second ' Echo received characters in infinite loop STX = 2 ETX = 3 Period = 46 TxBuf[1] = 51 TxBuf[2] = 54 TxBuf[3] = 56 mainloop: 'Collect 17 AD samples for A = 0 to 16 ADCIN 0, RawData[A] ' Read channel 0 to array Next A 'Now Lets sort the array Gosub SortArray 'Now Sum the middle 8 values for A = 4 to 11 ' pick out middle 8 readings DatAvg = DatAvg + RawData[A] NEXT A 'Now Divide by 8 (by shifting) too get an average DatAvg = DatAvg >>3 'Now put data in TxBuf For A=0 to 3 txbuf[A]= DatAvg DIG (3-A) next A for A = 0 to 3 TxBuf[A] = TxBuf[A] + 48 next A 'Send it! Gosub SendString ' Send character to serial output pause 500 ' Wait half second Goto mainloop ' Do it forever ' ' Sort Array ' ---------- SortArray: CounterA=0 SortLoop: If RawData(CounterA+1) < RawData(CounterA) then DataA=RawData(CounterA) RawData(CounterA)=RawData(CounterA+1) RawData(CounterA+1+0)=DataA If CounterA > 0 then CounterA=CounterA-2 endif CounterA=CounterA+1 If CounterA < 15 then goto SortLoop Return ' Subroutine to send a character string to USART transmitter 'First Send STX (02) then 2 digits, then period (46), then 1 digit, then ETX (03) SendString: 'Build Buffer SendBuf[0] = STX SendBuf[1] = TxBuf[0] SendBuf[2] = TxBuf[1] SendBuf[3] = TxBuf[2] SendBuf[4] = Period SendBuf[5] = TxBuf[3] SendBuf[6] = ETX 'Now Send it HSEROUT[STR SendBuf \ 7] Return ' Go back to caller
Bookmarks