I have been working on serial communications on Raspberry Pi using BBCSDL and have made some progress. Seeing some other questions about this I wanted to post my results for others but am not certain if content and formatting are correct. I am looking for some feedback and will try to get this into shape. Thanks for any help or suggestions.
The hardware setup is very simple. I am using an FTDI USB to serial converter on the Raspberry Pi side since that is by far the easiest. I am using a model 3 B+ and the FTDI converter was immediately recognized as ttyUSB0. I think that would be the case on any Pi except maybe Pi Zero. On the PC side the serial connection is plugged into a serial port.
I am posting 4 short test programs. There are 2 pairs, each with a PC side and a Raspberry Pi side. I tried to attach the programs but received a wrong file extension message so I am just embedding them in this post since they are so short.
First pair: PCsertest1.bas and RPisertest1.bas
RPisertest1.bas: A basic file, runs under BBCSDL. Opens the port and an output file to log results. Sends all possible bytes from 0 to 255 sequentially and then reads same byte echoed back by PC program and logs it. Exits after sending 0xFF. The program is located in /home/pi/Desktop/BBC/examples on my setup. BBCSDL is located in /home/pi/Desktop/BBC.
There are some statements in the program just to test various commands such as STR$, GET$, etc. As you can see the program as structured does not rely on being able to read the number of characters in the input buffer.
REM a test of serial port on Raspberry Pi 11/6/2018 SF
REM This program sends every ASCII character from 0 to 255, prints and logs the echoed characters and then quits
OSCLI "ldattach " + "-1 -8 -n -s 9600 0 /dev/ttyUSB0 " + ";"
OSCLI "stty " + "raw " + ";"
1 serial% = OPENUP("/dev/ttyUSB0.")
2 fileout% = OPENOUT("/home/pi/Desktop/BBC/examples/sertestoutpi.txt")
3 t% = 0
testbuf% = 0
fileout$ = STR$(fileout%)
serial$ = STR$(serial%)
4 PRINT#fileout%,fileout$," ",serial$," "
5 BPUT#fileout%,"Transmitting and Receiving Data"+CHR$(13)+CHR$(10)
6 FOR i% = 0 TO 255
7 BPUT#serial%,i%
10 t% = 0
t% = BGET#serial%
t$ = STR$(t%)
15 PRINT t$;" ";
16 PRINT#fileout%, t$
17 BPUT#fileout%, 32
20 NEXT i%
21 CLOSE#serial%
22 CLOSE#fileout%
23 END
PCsertest1.bas: This is the PC end of the test running under BBC BASIC V6.02a. It opens the port and a log file and then waits for a character. The timeout delay is set very long so that you can easily start PCsertest1.bas and then start the test program on the Pi. When the last byte (0xFF) is received the program terminates.
REM THIS IS THE PC END OF THE TEST PROGRAM FOR BBC BASIC SERIAL COMMS ON RASPBERRY PI
REM 11/6/2018 SF
serial% = OPENUP("COM1: baud=9600 parity=N data=8 stop=1")
fileout% = OPENOUT("C:\Sensigent\software\sertestoutpc.txt")
t% = 0
timeout% = 0
serial$ = STR$(serial%)
fileout$ = STR$(fileout%)
PRINT#fileout%,serial$,fileout$
BPUT#fileout%, "Receiving and Transmitting at PC"+CHR$(13)+CHR$(10)
10 testbuf = EXT#serial%
IF testbuf > 0 THEN
t% = BGET#serial%
PRINT t%;" ";
t$ = STR$(t%)
PRINT#fileout%, t$
BPUT#fileout%, 32
BPUT#serial%,t%
timeout% = 0
ENDIF
timeout% = timeout% + 1
IF timeout% > 3000000 THEN GOTO 20
IF t% <> 255 THEN GOTO 10
20 PRINT "Done"
CLOSE#serial%
CLOSE#fileout%
END
Second pair: PCsertest2.bas and RPisertest2.bas
PCsertest2.bas: Also running under BBC BASIC V6.02a. Since the first set of test already demonstrated all ASCII characters can be sent/received the PC side just sends the number of characters commanded by the user.
REM PC side for a test of serial port on Raspberry Pi
REM This one sends a specified number of characters each time through the loop
REM User inputs the number of characters to send. Entering 0 terminates program
10 serial% = OPENUP("COM1: baud=9600 parity=N data=8 stop=1")
PRINT "channel # ", serial%, " handle ", @hfile%(serial%)
20 INPUT k%
c% = 41
FOR i% = 0 TO k%-1
BPUT#serial%,c%
NEXT i%
IF k% > 0 THEN GOTO 20
CLOSE#serial%
END
RPisertest2.bas:
The Raspberry Pi side either checks and prints the number of characters in the buffer, or checks and, if non-zero, gets the characters in the buffer and prints them. This test program demonstrates the use of system calls to find the file designator and to determine the number of characters waiting in the serial input buffer.
REM THIS IS THE Pi END OF THE TEST PROGRAM FOR BBC BASIC SERIAL COMMS ON RASPBERRY PI
REM 11/27/2018 SF
REM Command line to open port, set parameters, and set line discipline to raw (no changes to characters)
OSCLI "ldattach " + "-1 -8 -n -s 9600 0 /dev/ttyUSB0 " + ";"
OSCLI "stty " + "raw " + ";"
REM Open the port and find the file designator used to check the input buffer for characters
serial% = OPENUP("/dev/ttyUSB0.")
SYS "fileno", @hfile%(serial%)!28 TO fildes%
REM "magic number" that tells IOCtl what you actually want to do, in this case check the serial buffer
FIONREAD = &541B
10 PRINT " "
PRINT "Channel # = "; serial%;" File Des = "; fildes%
tb% = 0
t% = 99
PRINT " "
PRINT " c = check buffer size , g = check buffer and get all chars, q = quit "
INPUT k$
IF k$ = "q" THEN GOTO 80
REM Use ioctl from command line to find number of characters in serial buffer
SYS "ioctl", fildes%, FIONREAD, ^tb% TO t%
PRINT "tb%=";tb%;" t%=";t%
IF k$="c" OR tb%=0 THEN GOTO 10
FOR i% = 1 TO tb%
c% = BGET#serial%
PRINT " Character # ";i%;" is ";c%
NEXT i%
GOTO 10
80 PRINT "Done"
CLOSE#serial%
END
That's it. I will check again in a few days to see if there is any feedback. Thanks.
Serial IO on Raspberry Pi with BBCSDL
Re: Serial IO on Raspberry Pi with BBCSDL
Listing the programs in [code] [/code] tags would have made them easier to read (and easier to copy/paste); one of the advantages of the forum is the ability to include formatted code listings in posts. Perhaps the admin might consider adding them to your message (if you don't).
There are examples of some pretty poor coding practices in the programs you listed: looping using 100% CPU time unnecessarily, implementing a timeout not actually based on time, and using GOTOs. I'm sure you are well aware how undesirable they are, but since these are simply demo programs illustrating a principle they may perhaps be forgiven. Just so long as you don't do the same things in a 'real' application!

-
- Posts: 78
- Joined: Sat 23 Jun 2018, 15:51
Re: Serial IO on Raspberry Pi with BBCSDL
To expand on Richard's comments it looks like you are a newcomer to BBC BASIC and many of the programming methods that are available to you.
So here are a few hints.
The 'Code' insert command is the 5th icon on the toolbar. That makes the code look like this below if you just paste your code between the tags.
Then there is the code itself. I cannot make any comment about its function as I don't have the hardware to run it on but I will make a couple of suggestions about programming style. We have all written code like that and years later we look at it and cringe, it is part of the learning process.
I have taken your program and I think have kept the same logic but now using a REPEAT to do the looping. And so that it does not zip around that loop at silly speed wasting CPU cycles and power I have added a WAIT statement. This hands control back to other threads or just sits idle for a wee while.
The arguments against GOTO are many but particularly it can lead to difficult to read code and makes it easy to make logical mistakes. Structured programming helps keep the logic more linear as it were. The indentation in the IDE also helps you see the loops and logical steps that GOTO obscures.
It does take a little thought to start with but quickly becomes second nature. For instance if you ever see a need to jump back to the start then a WHILE or REPEAT loop will probably do that better and more efficiently. If you ever see yourself using IF THEN GOTO to jump over some code then you can just invert the logic of the test make it into a multi-lined IF THEN and put the ENDIF where you wanted to jump to. Richard's additions to BBC BASIC allow you to EXIT from the structures if need be, and then the code 'falls through' to the code beyond that structure.
In this little code snippet the input of a "g" seems to be ignored. I imagine this is just 'work in progress'.
I think a little time looking at the example programs will be helpful with regards to the points above and also look at what happens when your code is run by people that will try all the silly inputs that you never thought of. Things like validating inputs and checking and reporting error conditions will be found on most of Richard's examples.
I hope this helps and welcome to the fold...
Z
So here are a few hints.
The 'Code' insert command is the 5th icon on the toolbar. That makes the code look like this below if you just paste your code between the tags.
Code: Select all
REM THIS IS THE Pi END OF THE TEST PROGRAM FOR BBC BASIC SERIAL COMMS ON RASPBERRY PI
REM 11/27/2018 SF
REM Command line to open port, set parameters, and set line discipline to raw (no changes to characters)
OSCLI "ldattach " + "-1 -8 -n -s 9600 0 /dev/ttyUSB0 " + ";"
OSCLI "stty " + "raw " + ";"
REM Open the port and find the file designator used to check the input buffer for characters
serial% = OPENUP("/dev/ttyUSB0.")
SYS "fileno", @hfile%(serial%)!28 TO fildes%
REM "magic number" that tells IOCtl what you actually want to do, in this case check the serial buffer
FIONREAD = &541B
REPEAT
PRINT " "
PRINT "Channel # = "; serial%;" File Des = "; fildes%
tb% = 0
t% = 99
PRINT " "
PRINT " c = check buffer size , g = check buffer and get all chars, q = quit "
INPUT k$
IF k$ = "q" THEN
PRINT "Done"
CLOSE#serial%
END
ENDIF
REM Use ioctl from command line to find number of characters in serial buffer
SYS "ioctl", fildes%, FIONREAD, ^tb% TO t%
PRINT "tb%=";tb%;" t%=";t%
IF k$<>"c" AND tb%<>0 THEN
FOR i% = 1 TO tb%
c% = BGET#serial%
PRINT " Character # ";i%;" is ";c%
NEXT i%
ENDIF
WAIT 1
UNTIL FALSE
PRINT "Escape"
CLOSE#serial%
END
I have taken your program and I think have kept the same logic but now using a REPEAT to do the looping. And so that it does not zip around that loop at silly speed wasting CPU cycles and power I have added a WAIT statement. This hands control back to other threads or just sits idle for a wee while.
The arguments against GOTO are many but particularly it can lead to difficult to read code and makes it easy to make logical mistakes. Structured programming helps keep the logic more linear as it were. The indentation in the IDE also helps you see the loops and logical steps that GOTO obscures.
It does take a little thought to start with but quickly becomes second nature. For instance if you ever see a need to jump back to the start then a WHILE or REPEAT loop will probably do that better and more efficiently. If you ever see yourself using IF THEN GOTO to jump over some code then you can just invert the logic of the test make it into a multi-lined IF THEN and put the ENDIF where you wanted to jump to. Richard's additions to BBC BASIC allow you to EXIT from the structures if need be, and then the code 'falls through' to the code beyond that structure.
In this little code snippet the input of a "g" seems to be ignored. I imagine this is just 'work in progress'.
I think a little time looking at the example programs will be helpful with regards to the points above and also look at what happens when your code is run by people that will try all the silly inputs that you never thought of. Things like validating inputs and checking and reporting error conditions will be found on most of Richard's examples.
I hope this helps and welcome to the fold...
Z
-
- Posts: 4
- Joined: Tue 18 Dec 2018, 20:23
Re: Serial IO on Raspberry Pi with BBCSDL
This is a continuation of my post from December 2018. The following example code will simulate sending a command from the Raspberry Pi and receiving a response from a device attached to the serial port. To keep the hardware simple the program only requires that the Rx and Tx pins be connected to each other. The pins can be connected either at a "logic" voltage level (typically 0 to 3.3 on the Pi) or the RS-232 level (typically about -5 and +5 volts these days). The program can also be used with a USB to serial adapter although you will need to substitute the proper ID for the port for "ttyAMA0" (usually ttyUSB0).
The only other code required is a very short script call "frag.sh" which stops the ldattach process used to configure the serial port if it is running when the program starts.
To use the program create a directory called "software" under your "Pi" home directory and place comtst.bas and frag.sh in the directory. Connect the Rx and Tx pins together at a convenient place then load and run the program with BBCSDL. The program has been tested with BBCSDL v1.17a.
Thanks to Richard Russell for his invaluable assistance with this test program. Please leave any comments or questions as a reply.
SteveF
Code: Select all
10 REM Initialize
20 fildes% = 0
30 FIONREAD = &541B
40 commopen% = 0
50 DIM tb{n%}
60 tb.n% = 0
70 tb% = 0
80 k% = 1
90 SERTIMEOUT = 100
100
110 REM Open serial port
120 OSCLI "*/home/pi/software/frag.sh"
130 OSCLI "ldattach " + "-1 -8 -n -s 9600 0 /dev/ttyAMA0 " + ";"
140 OSCLI "stty " + "-F /dev/ttyAMA0 " + "9600 " + "raw" + ";"
150 comm% = OPENUP("/dev/ttyAMA0.")
160 SYS "fileno", @hfile%(comm%)!28 TO fildes%
170 PRINT "Opened comm port on channel ", comm%, fildes%
180 REM Clear any garbage
190 WHILE FNLOB%
200 byte& = BGET#comm%
210 ENDWHILE
220
230 REM Send a variable number of characters from 1 to 12 terminated by new line
240 WHILE k% < 13
250 serout$ = ""
260 FOR i% = 1 TO k%
270 byte& = 64 + i%
280 BPUT#comm%,CHR$(byte&);
290 serout$ = serout$ + CHR$(byte&)
300 NEXT i%
310 BPUT#comm%,CHR$(10);
320
330 REM Receive the echoed characters (serial port is just looped back)
340 serin$ = ""
350 timeout = TIME + SERTIMEOUT
360 REPEAT
370 WAIT 0
380 lob% = FNLOB%
390 WHILE lob%
400 byte& = BGET#comm%
410 IF byte& <> 10 serin$ += CHR$(byte&)
420 lob% -= 1
430 ENDWHILE
440 UNTIL byte& = 10 OR TIME > timeout
450 IF byte& <> 10 THEN PRINT "Timeout!"
460
470 PRINT serout$ " " serin$
480 PRINT "k%=";k%;" LEN(serout$)=";LEN(serout$);" LEN(serin$)=";LEN(serin$)
490 IF serout$ <> serin$ THEN PROCrefreshPort
500 IF k% = 11 THEN PROCrefreshPort : REM Simulates a serial error o test closing and re-opening port
510 k%+=1
520 INPUT k$ : REM If you want to look at individual results
530 ENDWHILE
540
550 CLOSE#comm%
560 PRINT "DONE , type enter to exit "
570 INPUT k$
580 END
590
600 REM Check number of characters in input buffer
610 DEF FNLOB%
620 SYS "ioctl", fildes%, FIONREAD, tb{} TO commopen%
630 IF commopen% <> 0 THEN PRINT "FNLOB commopen%=";commopen%
640 tb% = tb.n%
650 =tb%
660
670 REM Close and re-open the serial port if something is not right
680 DEF PROCrefreshPort
690 LOCAL test$
700 WAIT 10
710 CLOSE#comm%
720 comm% = OPENUP("/dev/ttyAMA0.")
730 SYS "fileno", @hfile%(comm%)!28 TO fildes%
740 WHILE FNLOB%
750 byte& = BGET#comm%
760 ENDWHILE
770 PRINT "Closed and re-opened comm port on channel ", comm%, fildes%
780 WAIT 10
790 ENDPROC
Code: Select all
#!/bin/bash
kill -9 $(pidof ldattach)
echo "frag"
Thanks to Richard Russell for his invaluable assistance with this test program. Please leave any comments or questions as a reply.
SteveF
Re: Serial IO on Raspberry Pi with BBCSDL
As discussed elsewhere, I am not enthusiastic about this code:
Code: Select all
190 WHILE FNLOB%
200 byte& = BGET#comm%
210 ENDWHILE
Code: Select all
lob% = FNLOB%
WHILE lob%
byte& = BGET#comm%
lob% -= 1
ENDWHILE
Code: Select all
690 LOCAL test$
-
- Posts: 2
- Joined: Wed 19 Feb 2025, 22:31
Re: Serial IO on Raspberry Pi with BBCSDL
I'm sorry. Color me "dumb"... but...
If the first post could be edited to start with something like...
"These programs allow you to send or receive characters from a BBC BASIC program running in a Windows computer to/ from a command prompt window (putty session?) in a Raspberry Pi", I would find it easier to delve into the details on offer.
If the first post could be edited to start with something like...
"These programs allow you to send or receive characters from a BBC BASIC program running in a Windows computer to/ from a command prompt window (putty session?) in a Raspberry Pi", I would find it easier to delve into the details on offer.
-
- Posts: 272
- Joined: Tue 18 Jun 2024, 09:32
Re: Serial IO on Raspberry Pi with BBCSDL
But that's not what the programs do, surely? AIUI they enable two-way serial communication between the Raspberry Pi and another computer, using a USB serial adaptor and a standard serial (e.g. RS232) connection. Both ends use a BBC BASIC program, I don't think a terminal emulator like PuTTY comes into it.Sheepdog wrote: ↑Fri 14 Mar 2025, 18:04 If the first post could be edited to start with something like...
"These programs allow you to send or receive characters from a BBC BASIC program running in a Windows computer to/ from a command prompt window (putty session?) in a Raspberry Pi", I would find it easier to delve into the details on offer.
I suppose you could use PuTTY at either end to replace one of the BBC BASIC programs, but that's not the intention, unless I have misunderstood.