View previous topic :: View next topic |
Author |
Message |
atmega64
Joined: 23 Feb 2005 Posts: 298 Location: ITALY
|
Posted: Tue Oct 22, 2019 3:10 pm Post subject: Baudrate 9600 problem |
|
|
Hi,
I use an atmega1284 with a 16Mhz oscillator ..
if I use a baud rate of 9600, I have problems receiving the first character sent ... why?
Code: | $regfile = "m1284def.dat"
$crystal = 16000000
$baud = 9600
'**************
Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , Db7 = Porta.0 , E = Portc.5 , Rs = Portc.6
Config Lcd = 16 * 2
'**************
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Serialin = Buffered , Size = 254
Config Portd.6 = Output 'BUZZER
Buzzer Alias Portd.6
Declare Sub Bip
Dim Rx_cmd , Ric As Byte
Dim Command As String * 254
Enable Interrupts
Waitms 30
Initlcd
Cls
locate 1,1
lcd "HELLO"
bip
Command = ""
Ric = 0
Rx_cmd = 0
do
Rx_cmd = Ischarwaiting() 'CONTROLLA SE E' STATO RICEVUTO UN CARATTERE
If Rx_cmd = 1 Then
Rx_cmd = Waitkey() 'RITORNA IL VALORE DECIMALE RICEVUTO
Ric = 1
Command = Command + Chr(rx_cmd) 'INSERISCE I CARATTERI IN UNA STRINGA FINO A QUANDO LA TRASMISSIONE NON TERMINA
Waitms 1
Else
If Ric = 1 Then
Bip
Ric = 0
Cls
Locate 2 , 1
Lcd Command
Command = ""
End If
End If
loop
Sub Bip
Buzzer = 0
Waitms 20
Buzzer = 1
End Sub
end |
(BASCOM-AVR version : 2.0.8.1 , Latest : 2.0.8.2 ) |
|
Back to top |
|
|
AdrianJ
Joined: 16 Jan 2006 Posts: 2483 Location: Queensland
|
Posted: Tue Oct 22, 2019 11:21 pm Post subject: |
|
|
I would suspect that using ischarwaiting together with waitkey is the problem, at the least, one of them is redundant.
You do bufferend input, so IsCharWaiting tells you at least one character is in the buffer. Then just read it with inkey, you dont need to use waitkey, you already know there is a character there.
Depending on what you want to do, I find its usually better to put ischarwaiting in a loop, so it keeps adding characters to your output string untill the buffer is empty. At some point you get an end of line character, or carriage return, use that to determine when to output the completed string to the display.
Code: |
do
while Ischarwaiting() > 0 'CONTROLLA SE E' STATO RICEVUTO UN CARATTERE
Rx_cmd = inkey() 'RITORNA IL VALORE DECIMALE RICEVUTO
Ric = 1
if Rx_cmd = 13 ' pick whatever end of line character your string has
'a Select...Case statment works better here to pick out various characters
Bip
Cls
Locate 2 , 1
Lcd Command
Command = ""
else
Command = Command + Chr(rx_cmd) 'INSERISCE I CARATTERI IN UNA STRINGA FINO A QUANDO LA TRASMISSIONE NON TERMINA
Waitms 1 'you dont need this - just wastes valuable processor cycles
end if
wend
loop
|
_________________ Adrian Jansen
Computer language is a framework for creativity |
|
Back to top |
|
|
atmega64
Joined: 23 Feb 2005 Posts: 298 Location: ITALY
|
Posted: Wed Oct 23, 2019 2:00 pm Post subject: |
|
|
ok thanks…
but With "waitms 2" it works
Code: | Command = Command + Chr (rx_cmd)
Waitms 2 |
|
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Wed Oct 23, 2019 2:36 pm Post subject: |
|
|
both inkey and waitkey can be used in combination with ischarwaiting.
The waitms is indeed not needed.
The provided info given is not complete : we have no idea when the data is sent. Is the code running before the data is sent? And exactly what data is sent? En how much, etc. _________________ Mark |
|
Back to top |
|
|
AdrianJ
Joined: 16 Jan 2006 Posts: 2483 Location: Queensland
|
Posted: Wed Oct 23, 2019 11:03 pm Post subject: |
|
|
Thanks for the clarification Mark. I thought that waitkey might be waiting for the next character, after the one which set the ischarwaiting flag. In which case that one would be missed. _________________ Adrian Jansen
Computer language is a framework for creativity |
|
Back to top |
|
|
atmega64
Joined: 23 Feb 2005 Posts: 298 Location: ITALY
|
Posted: Thu Oct 24, 2019 7:22 am Post subject: |
|
|
albertsm wrote: | both inkey and waitkey can be used in combination with ischarwaiting.
The waitms is indeed not needed.
The provided info given is not complete : we have no idea when the data is sent. Is the code running before the data is sent? And exactly what data is sent? En how much, etc. |
Hi Mark,
- The code is running before the data is transmitted ...
- The transmitted data are strings of few characters, for example "HELLO" ...
putting waitms 2, it works ... what do you think?
this is the code: (can it be optimized?)
Code: |
$regfile = "m1284def.dat"
$crystal = 16000000
$baud = 9600
'**************
Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , Db7 = Porta.0 , E = Portc.5 , Rs = Portc.6
Config Lcd = 16 * 2
'**************
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Serialin = Buffered , Size = 254
Config Portd.6 = Output 'BUZZER
Buzzer Alias Portd.6
Declare Sub Bip
Dim Rx_cmd , Ric As Byte
Dim Command As String * 254
Enable Interrupts
Waitms 30
Initlcd
Cls
locate 1,1
lcd "HELLO"
bip
Command = ""
Ric = 0
Rx_cmd = 0
do
Rx_cmd = Ischarwaiting() 'CONTROLLA SE E' STATO RICEVUTO UN CARATTERE
If Rx_cmd = 1 Then
Rx_cmd = Waitkey() 'RITORNA IL VALORE DECIMALE RICEVUTO
Ric = 1
Command = Command + Chr(rx_cmd) 'INSERISCE I CARATTERI IN UNA STRINGA FINO A QUANDO LA TRASMISSIONE NON TERMINA
Waitms 2 '<<<<<<<<<<<<<<<<<<<
Else
If Ric = 1 Then
Bip
Ric = 0
Cls
Locate 2 , 1
Lcd Command
Command = ""
End If
End If
loop
Sub Bip
Buzzer = 0
Waitms 20
Buzzer = 1
End Sub
end |
|
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Thu Oct 24, 2019 8:58 am Post subject: |
|
|
I do not know what the goal of the code is?
It looks odd. There is no trailing character to check? Like a CR or LF ?
Usually you signal the end of a data stream with a trailing character like CR + LF or one of them.
your code seems to grab some data and when no data is available it resets.
so this is how it usually works :
Code: |
do
Rx_cmd = Ischarwaiting() 'CONTROLLA SE E' STATO RICEVUTO UN CARATTERE
If Rx_cmd = 1 Then
Rx_cmd = Waitkey() 'RITORNA IL VALORE DECIMALE RICEVUTO
if rx_cmd=13 then
Cls: Locate 2 , 1 :
Lcd Command 'show
Command = "" 'clear
else
Command = Command + Chr(rx_cmd) 'INSERISCE I CARATTERI IN UNA STRINGA FINO A QUANDO LA TRASMISSIONE NON TERMINA
end if
End If
loop
|
what you do is adding data, then set a flag. and once there is no data in the buffer, you show the data.
with waitms gives the sender more time to send data.
make 100% sure the code is running before you send data.
you can also simulate it and it will show that all data is captured.
it is also not clear if you mean from the first time you send data, or for each time you send data.
i would perform a simple test :
Code: |
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Serialin = Buffered , Size = 254
Config Portd.6 = Output 'BUZZER
Buzzer Alias Portd.6
Declare Sub Bip
Dim Rx_cmd , Ric As Byte
Dim Command As String * 254
Enable Interrupts
do
Rx_cmd = Waitkey() 'RITORNA IL VALORE DECIMALE RICEVUTO
print rx_cmd ' print ASCII value
loop |
that way you can see which data you receive.
and also important : do not forget to include $hwstack setting.the interrupt requires stack space. _________________ Mark |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Oct 25, 2019 8:11 am Post subject: |
|
|
atmega64 wrote: | this is the code: (can it be optimized?) |
Yes, by much, simply put your code in the trash bin, aka copy file to NUL.
Quote: | putting waitms 2, it works |
For this botchery you kept two forums busy. |
|
Back to top |
|
|
atmega64
Joined: 23 Feb 2005 Posts: 298 Location: ITALY
|
Posted: Fri Oct 25, 2019 2:48 pm Post subject: |
|
|
albertsm wrote: | I do not know what the goal of the code is?
It looks odd. There is no trailing character to check? Like a CR or LF ?
Usually you signal the end of a data stream with a trailing character like CR + LF or one of them.
|
Thanks Mark, I have been following this forum for years, and your advice has always been very valuable for me ... (the forum was born for this to give and receive help not for anything else … )
I explain it better:
I'm realizing a CCTALK communication between a micro and CCTALK devices (when I'm done I'll post the project on the forum … )
I already have a project I made on VB.net, which works fine, now I'm converting it to bascom.
The CCTALK protocol does not include the end of a data stream with a trailing character like CR + LF or one of them, but only the cheksum.
I managed to convert the VB.net code to transmit data, in bascom code, now I have to convert the code to receive the data.
The code for receiving data in VB.net is this:
Code: |
Do
If SerialPort1.BytesToRead > 0 Then 'there are bytes to read
'I read one byte at a time
LenRx += 1
ReDim Preserve RxByte(LenRx)
RxByte(LenRx) = SerialPort1.ReadByte
RxHex = HexConv(RxByte(LenRx), 2)
Buffer += RxHex 'the buffer contains transformed data in 2-digit hex
If LenRx = (MyCommand.Length / 2 + 1) Then 'the value of this byte identifies how many characters I will have in reception
AttLenRx = RxByte(LenRx) + 4 + LenCommand 'in this variable I insert the number of the data that I must receive in the serial port.
ReDim RxData(RxByte(LenRx - 1) - 1) 'in this matrix of bytes I insert only the data answered, as long as there is' -1 because it has a zero base.
End If
If AttLenRx > 0 Then
If LenRx >= AttLenRx Then 'IF ALL DATA HAVE BEEN RECEIVED, GET OUT OF THE RECEIVE CONTROL LOOP
Exit Do
End If
End If
End If
Loop
|
Any suggestions on what code I can use in BASCOM for:
If SerialPort1.BytesToRead > 0 Then
...
RxByte(LenRx) = SerialPort1.ReadByte
...
thank you all for your patience ... |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Fri Oct 25, 2019 4:55 pm Post subject: |
|
|
I never saw CCTALK protocol so I read Wikipedia https://en.wikipedia.org/wiki/CcTalk
I make quick test on the simulator
Code: | $regfile = "m1284def.dat"
$crystal = 16000000
$baud = 9600
$hwstack = 64
$swstack = 16
$framesize = 256
$sim
'CCTALK RECEIVER SIMULATION in BASCOM for checksum and overlay test
'TX data = 2 0 1 245 8
' 2 = destination address
' 0 = zero data bytes
' 1 = source address
' 245 = command header ‘Request equipment category id’
' 8 = checksum ( 2 + 0 + 1 + 245 + 8 = 256 = 0 mod 256 )
'This is a message from address 1 ( the host ) to peripheral address 2 to find out what it is.
'RX data = 1 13 2 0 67 111 105 110 32 65 99 99 101 112 116 111 114 22
' 1 = destination address
' 13 = 13 data bytes
' 2 = source address
' 0 = reply header
' 67…114 = ASCII for ‘Coin Acceptor’
' 22 = checksum ( sum of all packet bytes is zero )
'The Reply From Address 2 Back To Address 1 Identifies It As A Coin Acceptor.
Dim Rxbyte(255) As Byte
Dim Rxstring As String * 200 At Rxbyte(5) Overlay
'RX data = 1 13 2 0 67 111 105 110 32 65 99 99 101 112 116 111 114 22
Rxbyte(1) = 1
Rxbyte(2) = 13
Rxbyte(3) = 2
Rxbyte(4) = 0
Rxbyte(5) = 67
Rxbyte(6) = 111
Rxbyte(7) = 105
Rxbyte(8) = 110
Rxbyte(9) = 32
Rxbyte(10) = 65
Rxbyte(11) = 99
Rxbyte(12) = 99
Rxbyte(13) = 101
Rxbyte(14) = 112
Rxbyte(15) = 116
Rxbyte(16) = 111
Rxbyte(17) = 114
Rxbyte(18) = 22
Dim Helpb As Byte , N As Byte
For N = 1 To 18
Helpb = Helpb + Rxbyte(n)
Next
If Helpb = 0 Then
Rxbyte(18) = 0 'string terminator
Print Rxstring
End If
End |
Result was promissing
So I end up with this not tested code but you can try it
Probably it needs some tweaks because i work on both only half hour.
Code: | $regfile = "m1284def.dat"
$crystal = 16000000
$hwstack = 64
$swstack = 16
$framesize = 256
$baud = 9600
'CCTALK RECEIVER PART by EDC
Config Serialin = Buffered , Size = 100 'dont forget to enable interrupts!
Const Max_buff_len = 201
Const Max_cmd_len = Max_buff_len - 1
Dim Rxbyte (max_buff_len ) As Byte
Dim Rxstring As String * Max_cmd_len At Rxbyte (5) Overlay
Dim Mycrc As Byte , N As Byte
Dim Lenrx As Byte , Rxend As Byte
Enable Interrupts
Do
If 0 < Ischarwaiting() Then
Lenrx = 0 : Mycrc = 0 'we starting
Do
If 0 < Ischarwaiting() Then
Incr Lenrx
If Lenrx > Max_cmd_len Then 'buffor cant acomodate more data, error
Lenrx = 0 : Exit Do
End If
Rxbyte (lenrx ) = Waitkey()
If Lenrx = 2 Then Rxend = Rxbyte (lenrx ) + 5 'in second byte we get payload len
'but we must add 4B header and last byte for CRC
If Lenrx = Rxend Then 'ALL DATA WAS RECEIVED
For N = 1 To Rxend
Mycrc = Mycrc + Rxbyte (n )
Next
If Mycrc = 0 Then
Rxbyte (rxend ) = 0 'string terminator
Print Rxstring 'you can show this on LCD
Else
Print "CRC dont match"
End If
Exit Do 'exit because we dont aspect another byte
End If
'end Ischarwaiting
End If
Loop
End If
Loop
End |
Good luck |
|
Back to top |
|
|
atmega64
Joined: 23 Feb 2005 Posts: 298 Location: ITALY
|
Posted: Fri Oct 25, 2019 5:16 pm Post subject: |
|
|
thanks! of people like you need this forum ...
I will make tests and update you. |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Fri Oct 25, 2019 6:50 pm Post subject: |
|
|
Well done EDC. It is a good starting point.
I have done some commercial CCTALK apps. It is used in vending machines used on events.
One thing i like to warn for in general when i see serial reception code.
Thus not about your code but what i see in support : code that assumes that there will come data.
It is best never to assume that further data will arrive. There are different ways to deal with that.
first you can first count how much data is received. that way you know if you can read/process all data.
Another way is to use a simple state machine where you advance through states .
first you wait for data, when you have data you go to a next state. it is also important to consider timing. if for some time no data arrives you can reset your state.
because when you activate your code, you need to know what the data is. that what you think is the first byte is actually the first byte and not some data in the middle. of course you can check this with crc.
And you can use a WD timeout which is a rather cruel way. _________________ Mark |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
|
Back to top |
|
|
atmega64
Joined: 23 Feb 2005 Posts: 298 Location: ITALY
|
Posted: Tue Oct 29, 2019 8:40 pm Post subject: |
|
|
I obtained the BASCOM code from the VB.net code, which I had written ... and it works (obviously the timeout has to be managed etc ..)
a question ... there is a way in BASCOM to convert these commands to arrays ?
ReDim Preserve RxData (LenRx)
ReDim RxData (0)
CCTALK protocol reception code:
Code: |
Do
If Ischarwaiting(#2) = 1 Then 'If Serialport1.bytestoread > 0 Then 'ci sono byte da leggere
Ric = 1
'leggo un byte alla volta
Incr Lenrx
Rxbyte(lenrx) = Waitkey(#2)
Rxhex = Hexconv(rxbyte(lenrx) , 2)
Buffer = Buffer + Rxhex 'il buffer contiene dei dati trasformati in hex a 2 cifre
Mylen = Len(mycommand)
Xlen = Mylen / 2
Incr Xlen
If Lenrx = Xlen Then 'il valore di questo byte identifica quanti caratteri avrò in ricezione
Attlenrx = Rxbyte(lenrx) + 4
Attlenrx = Attlenrx + Lencommand 'in questa variabile inserisco il nuumero dei dati che devo ricevere nella porta seriale.
End If
Waitms 2
Else
If Ric = 1 Then 'Or Attlenrx > 0 And Lenrx >= Attlenrx Then
Ric = 0
Exit Do
End If
End If
Loop
Locate 2 , 1
Lcd Buffer
' Estrairisposta
Lenrx = 0
Rispostaascii = ""
For A = Lencommand + 4 To Attlenrx - 1
Rxdata(lenrx) = Rxbyte(a)
Incr Lenrx
If Rxbyte(a) = 0 Then
Rispostaascii = Rispostaascii + Chr(1) ' sostituisco il carattere zero perchè è un terminatore di stringa
Else
Rispostaascii = Rispostaascii + Chr(rxbyte(a))
End If
Next A
Locate 1 , 1
Lcd Rispostaascii | [/code] |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|