Oshonsoft programs with INTERRUPTS and PARSE

MrChips

Joined Oct 2, 2009
30,708
Arrays and strings are not the same.

You want to avoid using too many strings because all strings are allocated the same STRING_MAX_LENGTH storage
For handling incoming UART RX_Data it would be more efficient to use an array of byte.
For example,

Dim str1(80) as Byte

will allocate 80 bytes for incoming characters.
Keep an index of the next available empty location, for example,

rxi = 1

Store incoming characters into str1( )

char = RCREG
str1(rxi) = char
rxi = rxi + 1

and stop storing if you have reached the end of str1( ).
All of this is done in the interrupt service routine.

(I am simply repeating code examples already posted by Eric.)

My advice: Don't copy other people's code wholesale unless you fully understand each line of code. By learning how code works you will eventually come out of the woods and be able to see the light on your own.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Here is something to look.
It explains the registers and bits for the serial transmit and receive.
Interrupt setup is also needed.

https://openlabpro.com/guide/uart-interrupt-in-pic18f4550/
Hi J,
Sadly it is written in C, and I can't read it properly, and I've tried many times.

Your comment: "Actually Str1 in#36 is not a String variable, but an array of bytes (buffer)" is confusing as STR1 is set up with [ Dim str1(80) As Byte ] which to me is a variable, is this not true?
C
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Arrays and strings are not the same.

You want to avoid using too many strings because all strings are allocated the same STRING_MAX_LENGTH storage
For handling incoming UART RX_Data it would be more efficient to use an array of byte.
For example,

Dim str1(80) as Byte

will allocate 80 bytes for incoming characters.
Keep an index of the next available empty location, for example,

rxi = 1

Store incoming characters into str1( )

char = RCREG
str1(rxi) = char
rxi = rxi + 1

and stop storing if you have reached the end of str1( ).
All of this is done in the interrupt service routine.

(I am simply repeating code examples already posted by Eric.)

My advice: Don't copy other people's code wholesale unless you fully understand each line of code. By learning how code works you will eventually come out of the woods and be able to see the light on your own.
Hi Mr C,
As my last comment STR1() is shown in the 'watch variables', so does 'watch variables' look at BUFFERS also?
Confusing!
C.
 

MrChips

Joined Oct 2, 2009
30,708
The word buffer is a generic term used for temporary storage when moving data around, sometimes when the number of items is unknown and varying. The reason we call it a buffer is because we allocate ample space to absorb any amount of data thrown at us.

You can watch variables regardless of whether it is a string or array or single element.
 

jjw

Joined Dec 24, 2013
823
Hi J,
Sadly it is written in C, and I can't read it properly, and I've tried many times.

Your comment: "Actually Str1 in#36 is not a String variable, but an array of bytes (buffer)" is confusing as STR1 is set up with [ Dim str1(80) As Byte ] which to me is a variable, is this not true?
C
Str1 is an Array type variable of 80 bytes.
The name Str1 of the Array may be confusing.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Hi Mr C and J,
I see!
In the example I posted, there is an INTERRUPT, then a LOOP in the INTERRUPT where STR1() is incremented. If I understand correctly, I can still use STR1, but each BYTE of the $Sentence is incremented by the INTERRUPT, but in the MAIN LOOP.
I hope that's correct.
C
 

MrChips

Joined Oct 2, 2009
30,708
I have never used Oshonsoft BASIC.
If I were to use it I would test things in steps as I would with any platform.

Test your UART RX_Data interrupts first before trying to do anything else.
Code:
On Interrupt
'read the UART RX_Data
char = RCREG
'count how many characters received
rxi = rxi + 1 
Resume
In your main program, check how many characters received by displaying rxi.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
I have never used Oshonsoft BASIC.
If I were to use it I would test things in steps as I would with any platform.

Test your UART RX_Data interrupts first before trying to do anything else.
Code:
On Interrupt
'read the UART RX_Data
char = RCREG
'count how many characters received
rxi = rxi + 1
Resume
In your main program, check how many characters received by displaying rxi.
Hi Mr C,
Good idea, I'll make a test INTERRUPT program.
C
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Hi All,
I'm still a bit confused by STRING, BUFFER and ARRAY, so I think it's best that I make a start and post steps as I go along. This way I can build up the routine, hopefully correctly.
C.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Can you test the receiving of the message in real hardware?
Look at #47. Make a simple program first.
Hi J,
I've cleared most of the stuff from this new program, and have been testing the [ If PIR1.RCIF = 1 ] line, but so far it's not working.
Here's the program:
C
----------------------------------------------------------------------
'18LF4620 8MHz XTL BASE PCB_4 INTERRUPT ONLY 230420 1030
'ORDER HC-12, BMP280, AK8963C 5110, GPS.
Define CONFIG1L = 0x00
Define CONFIG1H = 0x02 '0x02 =EXT 8MHz
Define CONFIG2L = 0x1e
Define CONFIG2H = 0x00
Define CONFIG3L = 0x00
Define CONFIG3H = 0x81 'Set for HVP
Define CONFIG4L = 0x80
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40

Define SIMULATION_WAITMS_VALUE = 1 'Comment in for SIM out for PIC
Define CLOCK_FREQUENCY = 8
Define SINGLE_DECIMAL_PLACES = 2
Define STRING_MAX_LENGTH = 50 '70XXXXX

'SET PIN IN/OUT
TRISA = %00101111 '7=XTL 6=XTL 5=ANALOGUE IN (POT) 4=SERIN 18f4431 3210= ANALOGUE INPUTS (POTS)
TRISB = %00000000 '7=PGD 6=PGC 543210 SPARE
TRISC = %10010000 '7=RX=1, 6=TX=0, 5=SDO, 4=SDI=1, 3=SCK=0, 2=RLED, 1=YLED
TRISD = %00000000 '7=CS SPARE, 6=CS DATASW_S1, 5=CS DATASW_S0, 4=CS RADSET HC-12, 3=CS BMP280, 2=CS AK8963C_DRDY, 1=AK8963C_TRIG, 0=CS AK8963C_CS
TRISE = %00000000 '=Button
'SET BITS ON/OFF
PORTA = %00000000 'ON/OFF
PORTB = %00000000
LATB = 0
PORTC = %00000000
PORTD = %00000000
PORTE = %00000000 'POSS MCLR RE3
WaitMs 10

'SSPCON1 = %0010000 '5=Enables SCK,SDO,SDI as serial ports,
Symbol yled = LATE.1
Symbol rled = LATE.2

'START UP LEDS
yled = 1
rled = 1
WaitMs 1000
yled = 0
rled = 0
WaitMs 1000

Hseropen 9600
Hserout "READY", CrLf

Enable High '?????
'''''''''''Enable Low '????
rled = 0
yled = 0

Dim char As Byte


main: '\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

Toggle rled
'WaitMs 1000


Goto main
End

On High Interrupt
Save System


'If RCSTA.OERR = 1 Then 'BIT1..if over run error then flush RXD buffer
'RCSTA.CREN = 0
RCSTA.CREN = 1 'ENABLES RECEIVER
'char = RCREG '1
'char = RCREG '2
'PIR1.RCIF = 0 '0 = The EUSART receive buffer is empty
'Hserout "RX Err!", CrLf
'Endif

If PIR1.RCIF = 1 Then
Toggle yled
Break
Endif
Resume
--------------------------------------------------------------
 
Last edited:

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Can you test the receiving of the message in real hardware?
Look at #47. Make a simple program first.
Hi J,
It's now working.
I missed the Setup, Here:
------------------------------------------------------------
'set up interrupts
RCON.IPEN = 1 'IPEN: Int Priority Enable bit 'This MUST be included when using Interrupts (Priority HIGH/LOW)[#189 hserin blocking]
PIE1.RCIE = 1 'RCIE: EUSART Receive Interrupt Enable bit [ 1=en ]
INTCON.PEIE = 1 'PEIE/GIEL: Peripheral Interrupt Enable bit
INTCON.GIE = 1 'GIE/GIEH: Global Interrupt Enable bit
--------------------------------------------------------------
C
 
Last edited:

jjw

Joined Dec 24, 2013
823
Hi J,
I've cleared most of the stuff from this new program, and have been testing the [ If PIR1.RCIF = 1 ] line, but so far it's not working.
Here's the program:
C
----------------------------------------------------------------------
'18LF4620 8MHz XTL BASE PCB_4 INTERRUPT ONLY 230420 1030
'ORDER HC-12, BMP280, AK8963C 5110, GPS.
Define CONFIG1L = 0x00
Define CONFIG1H = 0x02 '0x02 =EXT 8MHz
Define CONFIG2L = 0x1e
Define CONFIG2H = 0x00
Define CONFIG3L = 0x00
Define CONFIG3H = 0x81 'Set for HVP
Define CONFIG4L = 0x80
Define CONFIG4H = 0x00
Define CONFIG5L = 0x0f
Define CONFIG5H = 0xc0
Define CONFIG6L = 0x0f
Define CONFIG6H = 0xe0
Define CONFIG7L = 0x0f
Define CONFIG7H = 0x40

Define SIMULATION_WAITMS_VALUE = 1 'Comment in for SIM out for PIC
Define CLOCK_FREQUENCY = 8
Define SINGLE_DECIMAL_PLACES = 2
Define STRING_MAX_LENGTH = 50 '70XXXXX

'SET PIN IN/OUT
TRISA = %00101111 '7=XTL 6=XTL 5=ANALOGUE IN (POT) 4=SERIN 18f4431 3210= ANALOGUE INPUTS (POTS)
TRISB = %00000000 '7=PGD 6=PGC 543210 SPARE
TRISC = %10010000 '7=RX=1, 6=TX=0, 5=SDO, 4=SDI=1, 3=SCK=0, 2=RLED, 1=YLED
TRISD = %00000000 '7=CS SPARE, 6=CS DATASW_S1, 5=CS DATASW_S0, 4=CS RADSET HC-12, 3=CS BMP280, 2=CS AK8963C_DRDY, 1=AK8963C_TRIG, 0=CS AK8963C_CS
TRISE = %00000000 '=Button
'SET BITS ON/OFF
PORTA = %00000000 'ON/OFF
PORTB = %00000000
LATB = 0
PORTC = %00000000
PORTD = %00000000
PORTE = %00000000 'POSS MCLR RE3
WaitMs 10

'SSPCON1 = %0010000 '5=Enables SCK,SDO,SDI as serial ports,
Symbol yled = LATE.1
Symbol rled = LATE.2

'START UP LEDS
yled = 1
rled = 1
WaitMs 1000
yled = 0
rled = 0
WaitMs 1000

Hseropen 9600
Hserout "READY", CrLf

Enable High '?????
'''''''''''Enable Low '????
rled = 0
yled = 0

Dim char As Byte


main: '\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

Toggle rled
'WaitMs 1000


Goto main
End

On High Interrupt
Save System


'If RCSTA.OERR = 1 Then 'BIT1..if over run error then flush RXD buffer
'RCSTA.CREN = 0
RCSTA.CREN = 1 'ENABLES RECEIVER
'char = RCREG '1
'char = RCREG '2
'PIR1.RCIF = 0 '0 = The EUSART receive buffer is empty
'Hserout "RX Err!", CrLf
'Endif

If PIR1.RCIF = 1 Then
Toggle yled
Break
Endif
Resume
--------------------------------------------------------------
See the manual.
You have to setup the USART receiver registers and interrupt control registers.

To set up an Asynchronous Reception:
1. Initialize the SPBRGH:SPBRG registers for the
appropriate baud rate. Set or clear the BRGH
and BRG16 bits, as required, to achieve the
desired baud rate.
2. Enable the asynchronous serial port by clearing
bit, SYNC, and setting bit, SPEN.
3. If interrupts are desired, set enable bit, RCIE.
4. If 9-bit reception is desired, set bit, RX9.
5. Enable the reception by setting bit, CREN.
6. Flag bit, RCIF, will be set when reception is
complete and an interrupt will be generated if
enable bit, RCIE, was set.
7. Read the RCSTA register to get the 9th bit (if
enabled) and determine if any error occurred
during reception.
8. Read the 8-bit received data by reading the
RCREG register.
9. If any error occurred, clear the error by clearing
enable bit, CREN.
10. If using interrupts, ensure that the GIE and PEIE
bits in the INTCON register (INTCON<7:6>)


Edit: I was writing about the setup when you were correcting it :)
 
Last edited:

MrChips

Joined Oct 2, 2009
30,708
Do this things one step at a time.

1) In your main loop, make an LED toggle at a certain rate.
Show your code.

2) Remove the LED toggle feature.
Make an LED come ON when a switch or button is pressed, OFF when switch is released.
Show your code.

I know that you must have done these things before. Let's do them anyway just to make sure we know where we are.
If you do not understand any line of code don't be afraid to ask.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
Do this things one step at a time.

1) In your main loop, make an LED toggle at a certain rate.
Show your code.

2) Remove the LED toggle feature.
Make an LED come ON when a switch or button is pressed, OFF when switch is released.
Show your code.

I know that you must have done these things before. Let's do them anyway just to make sure we know where we are.
If you do not understand any line of code don't be afraid to ask.
Hi Mr C,
This is working:
If you have a Simulator, type anything into the [ SEND STRING ] in the Hardware UART.
Much appreciated.
C.
 

Attachments

MrChips

Joined Oct 2, 2009
30,708
I am not simply checking to see if code is working or not.
The main purpose is to develop a methodical test sequence so that you can have full confidence of what is working and what isn't.

It is not good enough to declare something is working or not working. When it is not working you need to be able in identify and pinpoint what is not working.

If you have an oscilloscope it will help tremendously in debugging complex SW and HW systems.
Without an oscilloscope you have to come up with creative ways to test your code.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,724
I am not simply checking to see if code is working or not.
The main purpose is to develop a methodical test sequence so that you can have full confidence of what is working and what isn't.

It is not good enough to declare something is working or not working. When it is not working you need to be able in identify and pinpoint what is not working.

If you have an oscilloscope it will help tremendously in debugging complex SW and HW systems.
Without an oscilloscope you have to come up with creative ways to test your code.
Hi Mr C,
I have an oscilloscope, and have used it a lot to get the earlier program.

I'm not a defeatest, but from experience, we will spend a lot of time going round in circles. I'm not good at programming, and have a lot of experience, at not being good. I'm just about capable of small CODE adjustments while using the simulator. It's a kind of dyslexia, and I do make every effort.

The last couple of days has been frustrating, and that's to get the LEDs to work. Also the program I'm trying to fix, has taken over 5 years, with lots of help similar to yours, that wasn't helped by issues with Oshonsoft, which took some time to iron out, so If you'll bear with me, I'll go back to the earlier almost working program, and see if I can follow the suggestions, including a minimal INTERRUPT, and get it going that way.

Sorry, and thanks for your encouragement.
C.
 

MrChips

Joined Oct 2, 2009
30,708
If you have an oscilloscope then use it. It gives better information than an LED at high frequencies.

Write a main loop to toggle an LED without using delay.
Show your code and report back.
 

jjw

Joined Dec 24, 2013
823
Hi Mr C,
This is working:
If you have a Simulator, type anything into the [ SEND STRING ] in the Hardware UART.
Much appreciated.
C.
Receiver is not enabled.
It gets now the interrupt from other source, probably TX interrupt.
You should setup the receiver, look #54
Setup the interrupts only for the receiver.
 
Top