Continue to Site

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.

  • 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.

Uart rx communication problem

Status
Not open for further replies.

revave

Member
Hello,

For the next problem i need the input from this forum again :)

Situation:
A PIC16F628A or 16F690 and a BC04 bluetooth module.

I've made a simple test program for reading and sending some data to my smartphone.
Therefore i've downloaded different applications which can send and recieve data via bluetooth.
Finaly i send max one byte each time.

Sending data from PIC to BC04 works without any problem. I can read data at my smartphone.
Retrieving data from the smartphone via the BC04 is not working.
I can see a short flickering at the led connected to the rx line, but the rx-buffer seems to stay empty.
At first i used the hserin command (ignoring the PIR1.RCIF bit, which i want to use at a later stadium).
The program is waiting for data, but it doesn't detect new data.

At second i've tried the hserget command, but it doesn't matter.

When i use the software UART (serin) i can see some data, but it is not stable.

I've attached the code with the HSERIN command. Do I need some pull-up or pull down resistors?
Can it be possible that i need some more settings for UART communication?

I prefer the HSERIN command for my final program with the condition that PIR1.RCIF = true.
So in my program i will write:
IF PIR1.RCIF = true THEN
Hserin bt_value 'bt_value is a variabele of datatype byte
endif

Any suggestions why restrieving serial data doesn't work?

testcode:
Code:
Define CONFIG = 0x3f50
Define CLOCK_FREQUENCY = 4
AllDigital
 
Define LCD_BITS = 4  'allowed values are 4 and 8 - the number of data interface lines
Define LCD_DREG = PORTA
Define LCD_DBIT = 0  '0 or 4 for 4-bit interface, ignored for 8-bit interface
Define LCD_RSREG = PORTA
Define LCD_RSBIT = 6
Define LCD_EREG = PORTA
Define LCD_EBIT = 7
Define LCD_COMMANDUS = 100  'delay after LCDCMDOUT, default value is 5000
Define LCD_DATAUS = 50  'delay after LCDOUT, default value is 100
Define LCD_INITMS = 50  'delay used by LCDINIT, default value is 100
'the last three Define directives set the values suitable for simulation; they should be omitted for a real device
 
Dim bt(5) As Byte
ConfigPin PORTB.1 = Input
ConfigPin PORTB.2 = Output
Dim teller As Word
 
Lcdinit 1  'initialize LCD module; cursor is blinking
Lcdcmdout LcdClear  'clear LCD display
Lcdout "boot up"
Hseropen 9600
 
loop:
 
    teller = teller + 1
    WaitMs 500
    bt(5) = bt(4)
    bt(4) = bt(3)
    bt(3) = bt(2)
    bt(2) = bt(1)
    bt(1) = bt(0)
 
Hserin bt(0)
    Lcdcmdout LcdClear
    Lcdout #bt(0), "_", #bt(1), "_", #bt(2), "  "  'text for the line 1
    Lcdcmdout LcdLine2Home  'set cursor at the beginning of line 2
    Lcdout #bt(3), "_", #bt(4), "_", #bt(5), "  "  'formatted text for line 2
    WaitMs 1000
    Hserout #teller
Goto loop  'loop forever
 
Last edited:
Hi,

The software UART itself is working now, but this means that my program is waiting for new data. The program will not execute further until new data is retrieved. Is there a possibility that my program will keep running, even if there is no new data?
I've been thinking about a similar function like the PIR1.RCIF flag. I've tried to detect the Rx port, but that doesn't give the expected result..

Any suggestions?
 
You really need to get it working without the bluetooth... If you hard wire the two together and see if your serial code works first.... Then you can move on..

The best way is via an interrupt... Then you can just let the interrupt deal with the receiving and just gives you a nudge when anything has been received...
 
You really need to get it working without the bluetooth... If you hard wire the two together and see if your serial code works first.... Then you can move on..

The best way is via an interrupt... Then you can just let the interrupt deal with the receiving and just gives you a nudge when anything has been received...

Hi,

For a test i connected the Tx at the Rx port of the same PIC.
When using the hardware UART i'm sending a byte from Tx to Rx. Nothing happened. The PIR1.RCIF flag doesn't get high.
The problem is that the Rx buffer doesn't detect any new data . A led connected to the Rx pin tells me that new data is written to the Rx pin.
I also tried to communicate with pull-up resistors, but that doesn't have any effect in the software. Connecting a oscilloscoop to Rx tells me that the Rx pin recieves some pulses, but it is to fast to check these bits. If I read the errorcode of the state registers, i do not see any error.

If i want to use the Software UART, is there any option to break the Serin instruction of the Software UART?
 
hi,
Your original program works OK in the Oshonsoft simulator, using the HW Uart tool.
Have you tried it in simulation.?
E
 
Your code isn't looking for the RCIF.... The RCIE must be set if you want to use the interrupt flag!!

Oshonsoft basic uses a "Polled" serial communication..... If you need interrupts you'll need to set them up yourself.
 
Here's a small example of my interrupt routine for interrupt reception.

Code:
Hseropen 19200
; set up interrupts
PIE1.RCIE = 1
INTCON.PEIE = 1
INTCON.GIEH = 1

'main loop
'---------
main:
    If outptr > 0 Then  ; A valid packet has arrived
           Call send() ; reply
            outptr = 0
    Endif
    WaitMs 100
    Goto main
End                                             
On High Interrupt
    Save System
    If RCSTA.OERR = True Then   ; any error reboot serial module..
            RCSTA.CREN = 0
            RCSTA.CREN = 1
            Goto fin
    Endif  
    buffer(inptr) = RCREG   ; get character ( reading clears the RCIF )
    If buffer(inptr) = 0xd Then outptr = inptr   ; set software flag when LF has arrived
    inptr = inptr + 1
    If inptr = 10 Then inptr = 0   ; 10 position circular buffer
fin:
Resume
 
Here's a small example of my interrupt routine for interrupt reception.

Code:
Hseropen 19200
; set up interrupts
PIE1.RCIE = 1
INTCON.PEIE = 1
INTCON.GIEH = 1
 
'main loop
'---------
main:
    If outptr > 0 Then  ; A valid packet has arrived
           Call send() ; reply
            outptr = 0
    Endif
    WaitMs 100
    Goto main
End                                            
On High Interrupt
    Save System
    If RCSTA.OERR = True Then   ; any error reboot serial module..
            RCSTA.CREN = 0
            RCSTA.CREN = 1
            Goto fin
    Endif 
    buffer(inptr) = RCREG   ; get character ( reading clears the RCIF )
    If buffer(inptr) = 0xd Then outptr = inptr   ; set software flag when LF has arrived
    inptr = inptr + 1
    If inptr = 10 Then inptr = 0   ; 10 position circular buffer
fin:
Resume


Hello Ian,

Thank you for your example.
With a part of your code i recieve data in the RCREG buffer.
So, the interupt routine works fine. Only problem is the data itself. If I send low numbers in hex-format, i only see decimal values like 243, 245, 247 in the RCREG buffer. I do not send any LF or CR..
I think i am missing something stupid :)
Any idea what this could be?
 
You can modify the example to set "outptr" when one char has arrived....
Hex numbers and decimal numbers are the same..... The only difference is the viewer you are using to see them.

247, 245 and 243 is the same as 0xF5, 0xF4 and 0xF3...
 
You can modify the example to set "outptr" when one char has arrived....
Hex numbers and decimal numbers are the same..... The only difference is the viewer you are using to see them.

247, 245 and 243 is the same as 0xF5, 0xF4 and 0xF3...

Hello Ian,

I know that they are the same. But the problem is:

to MCU hex | revieved in RCREG dec
0x0a | 243
0x0f | 243
0x14 | 240
0x19 | 242
0x1E | 243
0x23 | 245

So, there is something going wrong. I send low values (10,15,20,15,30,35) to the MCU but the RCREG buffer gave me these high values..
 
I had exactly this problem, but it was on a 18F series PIC, so it might not be relevant.

Turning off the background bebugger solved the problem.
 
Update communication:
Because the software is working fine at this moment, i will write an update. Maybe it could be helpfull for someone else.
The first uart test was done with a 16F628A and a BC04 bluetooth module. After many problems with comunication and with help of the comments to this topic i've change the PIC type and tried again.
Now, with another PIC (16F887) it works fine. Even the standard oshonsoft code is working (Hserout & Hserin). It all had to do with fault handling. The code from Ian Rogers was a good leading to the final result. Before making a new connection between the BC04 (bluetooth module) and the PIC, i've checked all communications with a notebook. Therefore a MAX 232(A) is needed for voltage level converting. That gave me the impression that both components are working properly. Last step was connection of the BC04 to the PIC. Level convertion is not necessary here. The connection of the BC04 to the notebook told me that this module will send some characters every time a connection is established. This can result in an error of the pic uart. So, the RCSTA registry must be checked to reset the error if it exists (RCSTA.OERR) before reading the uart buffer. Then the serial interface is working fine (thank you Ian).
I think it also should work with the 16F628A, but maybe the uart was damaged by trying al lot of things to get the communication done...
Thank you all for your comments to solve this problem!
 
Last edited:
Status
Not open for further replies.

Latest threads

Back
Top