This is a follow-on from the "Problem with PEEK" discussion.
With the code below, I'm trying to poll for an address and display a particular character if the address is received. For example, if the data received is "21" and the address is 2, then the display should show 1. A special case is if the first byte received is "!" in which case, each display should show its address.
I'm sending the data from one PIC to another and have been able to confirm using Hyperterminal that my PIC is sending the data correctly (at 9600 baud rate). However, the chip with the receive code is not displaying the data received.
Is there something wrong with my code? Or is there something I should know about the hardware required to have the PIC receive the date correctly?
Note: the AddressSelection and DisplayStartup subs are working correctly
As I write this, I see I have the InitSer within the "Main: - goto Main" loop. Should this be before the loop commences? Before the AddressSelection and DisplayStartup calls?
IF RecData(1) = "!" THEN
DisplayValue 1, Address
END IF
IF RecData(1) = Address THEN
IF RecData(2) <= 9 THEN
DisplayValue 1, RecData(2)
END IF
IF RecData(2) !<= 9 THEN
DisplayChar 1, RecData(2)
END IF
END IF
goto Main
SUB DisplayStartup
EPRead(0, Address)
For i = 0 to 9
Shorted = Peek (6)
DisplayValue 1, i
Wait 15 10ms
Next
DisplayValue 1, Address
Wait 50 10ms
Return
Sub AddressSelection
Shorted = Peek (6)
IF Shorted.4 ON THEN
Loop:
For i = 0 to 9
Shorted = Peek (6)
IF Shorted.4 OFF THEN
Address = i - 1
EPWrite (0, Address)
Return
END IF
DisplayValue 1, i
Wait 50 10ms
Next
If PortB.4 ON THEN
goto Loop
END IF
END IF
Return
sub SerRead (Channel, SerReadData(), numbytes)
for Counter = 1 to numbytes
SerReceive Channel, SerReadData(Counter)
next
end sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
There a couple of syntax errors that GCBASIC isn't reporting, and a couple of minor changes that I'd recommend.
The line
IF RecData(1) = "!" THEN
will not compile properly, as GCBASIC treats anything between quotes as a string. I'm currently making some changes to the compiler that will make this line valid, but for now you'll need to change it to:
IF RecData(1) = 33 THEN
(33 is the ASCII code for !)
This line also has an error:
IF RecData(2) !<= 9 THEN
This needs to be changed to
IF RecData(2) > 9 THEN
I've made some more changes to GCBASIC so that it will pick this up in future - I'll upload the new version once I've dealt with some other major issues in it.
A minor alteration which I'd make is to get rid of the Peeks - if you're just accessing the one address, it's better to refer to PORTB directly. Shorted = Peek (6) would become Shorted = PORTB.
Other than what I've mentioned, your code looks fine. The placement of InitSer should make no difference as long as it is called before any other serial routine.
There could also be some timing issues with the serial routines, but that's just a vague suspicion. Could you try logging the serial data received to the EEPROM?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Using strings as variables/constants seems weird to me. Why not just use a name convention in your defines? Define Welcome 33 '!, much more flexible.
Hopefully Hugh's suggestions will get your software Usart going. Would changing to an extra stop bit (2) help? Using the hardware Usart gives you a double byte buffer on the the receiving end, which may be useful. I have been using the hardware Usart, given by Steve Bell, with no problems.
Are you still working on the two scoreboard project? If you end up using the hardware Usart, would you add another Pic, or use an addressing scheme? The 9th bit address, master to slave thing, would be interesting project in itself. This of course, is assuming the Usart is "The" solution to your project.
Kent
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hugh - I like the EEPROM idea - I'll go with that to see that my chip is receiving the data. I'd since picked up the two errors you pointed out. Thanks for the ASCII character for the !.
For some reason, when I was compiling it wasn't erroring out on the '!<=' - In fact I'd put this in because 'IF NOT RecData(2) <= 9 THEN' had errored out. What I'm trying to determine with the two IF statements is if it's a number, then call the DisplayValue routine and if it's a letter, then call the DisplayChar routine. Will GCBasic pick up that 'a' is greater than '9'?
RE Peek - I had tried using Shorted = PORTB. but this caused the whole thing to work erratically. It would continue to run through the loop even after I'd removed the jumper between the +'ve voltage and Port B.4. Is having Peek in there going to adversely affect the rest of the code? The AddressSelection sub is only called on startup and is then never called again.
Kent - most of what you've just said has gone *whoosh* straight over me... I am a newbie and this is a bigger project than I'd intended to dip my feet into the PIC pool with, but what can you do? By the way, this is for the dual scoreboard project. Although, with time against me, it's more likely that I'll just go with the one scoreboard for now. The second scoreboard is exactly the same as the first board, with the console containing the LCD being the third element to the project.
RE strings - my intention was to load the data recieved into an array. GCBasic doesn't differentiate between a string and an array? What if I had two variables AddressByte and ValueByte, and instead of loading the two bytes received into the array, load them into these two variables. Would this be better?
Thanks,
Grant
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
For i = 0 to 9
Shorted = Peek (6)
IF Shorted.4 OFF THEN
Address = i - 1
This will give you a negative address number, not good.
The code seems overly complicated for just to send out startup message. Why not just have the slave listen for a unique number then spit out a string message?
For an idea of what I am talking about; Here's an example of how I listen in for a button press from a master, using the hardware Usart. The code works, but is a little kludgy, and could use more work. Excuse some extra copy and paste artifacts from the master code.
'#include <ascii.h> not needed here because no variables used
#include <HrdwrUsart.h>
#define Transmit PORTB.3
'#define PB PortA.1
'#define TxOut PortB.2
'dir PortA.1 in
dir PortB.1 in
dir PORTB.2 out
dir PORTB.3 out
SetupSerial '9600 baud, 8/N/1 no flow control
Main:
Loopx:
Character = ReceiveSerial
If flags.gotnewdata OFF then GOTO Loopx
If Character = 1 Then
TransmitSerial_Print("Hello")
Set Transmit On
End if
If Character = 0 Then Set Transmit Off
wait 2 sec
Set flags.gotnewdata OFF
wait 25 ms
goto Main
Good luck,
Kent
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi All,
This is a follow-on from the "Problem with PEEK" discussion.
With the code below, I'm trying to poll for an address and display a particular character if the address is received. For example, if the data received is "21" and the address is 2, then the display should show 1. A special case is if the first byte received is "!" in which case, each display should show its address.
I'm sending the data from one PIC to another and have been able to confirm using Hyperterminal that my PIC is sending the data correctly (at 9600 baud rate). However, the chip with the receive code is not displaying the data received.
Is there something wrong with my code? Or is there something I should know about the hardware required to have the PIC receive the date correctly?
Note: the AddressSelection and DisplayStartup subs are working correctly
As I write this, I see I have the InitSer within the "Main: - goto Main" loop. Should this be before the loop commences? Before the AddressSelection and DisplayStartup calls?
Thanks,
Grant
#chip PIC16F690, 20
#config _CP_OFF & _CPD_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_CLKOUT
#define DisplayPortA PORTC
#define RecAHigh PORTA.5 ON
#define RecALow PORTA.5 OFF
Wait 100 10ms
dir C 0
dir B 1
dir PortA.5 IN
Dim Address As Byte
dim Shorted As Word
Dim RecData(2)
goSub AddressSelection
goSub DisplayStartup
Main:
InitSer (1, r9600, 1+WaitForStart, 8, 1, none, normal)
SerRead (1, RecData$, 2)
IF RecData(1) = "!" THEN
DisplayValue 1, Address
END IF
IF RecData(1) = Address THEN
IF RecData(2) <= 9 THEN
DisplayValue 1, RecData(2)
END IF
IF RecData(2) !<= 9 THEN
DisplayChar 1, RecData(2)
END IF
END IF
goto Main
SUB DisplayStartup
EPRead(0, Address)
For i = 0 to 9
Shorted = Peek (6)
DisplayValue 1, i
Wait 15 10ms
Next
DisplayValue 1, Address
Wait 50 10ms
Return
Sub AddressSelection
Shorted = Peek (6)
IF Shorted.4 ON THEN
Loop:
For i = 0 to 9
Shorted = Peek (6)
IF Shorted.4 OFF THEN
Address = i - 1
EPWrite (0, Address)
Return
END IF
DisplayValue 1, i
Wait 50 10ms
Next
If PortB.4 ON THEN
goto Loop
END IF
END IF
Return
sub SerRead (Channel, SerReadData(), numbytes)
for Counter = 1 to numbytes
SerReceive Channel, SerReadData(Counter)
next
end sub
There a couple of syntax errors that GCBASIC isn't reporting, and a couple of minor changes that I'd recommend.
The line
IF RecData(1) = "!" THEN
will not compile properly, as GCBASIC treats anything between quotes as a string. I'm currently making some changes to the compiler that will make this line valid, but for now you'll need to change it to:
IF RecData(1) = 33 THEN
(33 is the ASCII code for !)
This line also has an error:
IF RecData(2) !<= 9 THEN
This needs to be changed to
IF RecData(2) > 9 THEN
I've made some more changes to GCBASIC so that it will pick this up in future - I'll upload the new version once I've dealt with some other major issues in it.
A minor alteration which I'd make is to get rid of the Peeks - if you're just accessing the one address, it's better to refer to PORTB directly. Shorted = Peek (6) would become Shorted = PORTB.
Other than what I've mentioned, your code looks fine. The placement of InitSer should make no difference as long as it is called before any other serial routine.
There could also be some timing issues with the serial routines, but that's just a vague suspicion. Could you try logging the serial data received to the EEPROM?
Using strings as variables/constants seems weird to me. Why not just use a name convention in your defines? Define Welcome 33 '!, much more flexible.
Hopefully Hugh's suggestions will get your software Usart going. Would changing to an extra stop bit (2) help? Using the hardware Usart gives you a double byte buffer on the the receiving end, which may be useful. I have been using the hardware Usart, given by Steve Bell, with no problems.
Are you still working on the two scoreboard project? If you end up using the hardware Usart, would you add another Pic, or use an addressing scheme? The 9th bit address, master to slave thing, would be interesting project in itself. This of course, is assuming the Usart is "The" solution to your project.
Kent
Thanks Hugh and Kent,
Hugh - I like the EEPROM idea - I'll go with that to see that my chip is receiving the data. I'd since picked up the two errors you pointed out. Thanks for the ASCII character for the !.
For some reason, when I was compiling it wasn't erroring out on the '!<=' - In fact I'd put this in because 'IF NOT RecData(2) <= 9 THEN' had errored out. What I'm trying to determine with the two IF statements is if it's a number, then call the DisplayValue routine and if it's a letter, then call the DisplayChar routine. Will GCBasic pick up that 'a' is greater than '9'?
RE Peek - I had tried using Shorted = PORTB. but this caused the whole thing to work erratically. It would continue to run through the loop even after I'd removed the jumper between the +'ve voltage and Port B.4. Is having Peek in there going to adversely affect the rest of the code? The AddressSelection sub is only called on startup and is then never called again.
Kent - most of what you've just said has gone *whoosh* straight over me... I am a newbie and this is a bigger project than I'd intended to dip my feet into the PIC pool with, but what can you do? By the way, this is for the dual scoreboard project. Although, with time against me, it's more likely that I'll just go with the one scoreboard for now. The second scoreboard is exactly the same as the first board, with the console containing the LCD being the third element to the project.
RE strings - my intention was to load the data recieved into an array. GCBasic doesn't differentiate between a string and an array? What if I had two variables AddressByte and ValueByte, and instead of loading the two bytes received into the array, load them into these two variables. Would this be better?
Thanks,
Grant
For i = 0 to 9
Shorted = Peek (6)
IF Shorted.4 OFF THEN
Address = i - 1
This will give you a negative address number, not good.
The code seems overly complicated for just to send out startup message. Why not just have the slave listen for a unique number then spit out a string message?
For an idea of what I am talking about; Here's an example of how I listen in for a button press from a master, using the hardware Usart. The code works, but is a little kludgy, and could use more work. Excuse some extra copy and paste artifacts from the master code.
'Chip model
#chip 16f648a,4
#config _CP_OFF &_WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _LVP_OFF '& DP_OFF
'#include <ascii.h> not needed here because no variables used
#include <HrdwrUsart.h>
#define Transmit PORTB.3
'#define PB PortA.1
'#define TxOut PortB.2
'dir PortA.1 in
dir PortB.1 in
dir PORTB.2 out
dir PORTB.3 out
SetupSerial '9600 baud, 8/N/1 no flow control
Main:
Loopx:
Character = ReceiveSerial
If flags.gotnewdata OFF then GOTO Loopx
If Character = 1 Then
TransmitSerial_Print("Hello")
Set Transmit On
End if
If Character = 0 Then Set Transmit Off
wait 2 sec
Set flags.gotnewdata OFF
wait 25 ms
goto Main
Good luck,
Kent