I have problem using INPUT$. I use version picomite 6.00.01 on a RP2350.
The serial port work for ouput but input$ always retrun an empy string.
LOC(#1) give me a value greater than zero. But INPUT$ always return an empy string.
SETPIN GP0, GP1, COM1 OPEN "COM1:115200" AS #1
IF LOC(#1) > 10 THEN data$ = INPUT$(256, #1)
Any idea ?
Best regards Georges
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2940
Posted: 10:38am 09 Jun 2025
May not work but worth a try. Add a pause to allow processing to complete.
IF LOC(#1) > 10 THEN Pause 10 data$ = INPUT$(256, #1) EndIf
CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 2171
Posted: 11:05am 09 Jun 2025
maybe I am not up to date on Pico MMBasic, but it looks like you are trying to get 256 charcaters... the maximum in a string is 255. Maybe that is some obscure "gotcha"
try something like:
b$=Input$(Min(10,Loc(#2)),#2)
to grab however many characters are available or just 10, whichever is the lower
h Edited 2025-06-09 21:09 by CaptainBoing
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2940
Posted: 11:07am 09 Jun 2025
Well spotted, I completely missed that.
mozzie Senior Member Joined: 15/06/2020 Location: AustraliaPosts: 196
Posted: 11:32am 09 Jun 2025
G'day Georges, The following might explain the situation.
OPEN "COM1:115200" as #1 When the serial port is opened, the receive buffer is cleared.
IF LOC(#1) > 10 THEN data$ = INPUT$(256, #1) Now we check the buffer, which is empty, so data$ is also empty.
So we need to wait for the data to arrive:
OPEN "COM1:115200" as #1 Do while LOC(#1)<10 ' loop here until 10 chars in input buffer Loop data$ = INPUT$(255, #1) print data$
You can also use interrupts but hopefully this will help.
I already spend many hours with this problem. Here is the complete explanation.
The sender send 50 bytes every 10 mS.
I use SETTICK to read the serial port every 10 ms.
The routine I call :
PRINT LOC(#1) give +/- 100
data$=input$(100,#1) give an empty string
PRINT LOC(#1) give again +/- 100
' Then I clear the buffer
DO g$=input$(100,#1) LOOP UNTIL LOC(#1)=0
I think it is a timing problem. Things goes too far. We can not read datas during datas is coming.
What do you thinks guy ?
Best regards Georges
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 1693
Posted: 02:10pm 09 Jun 2025
I have found the serial communications to be rock-solid (standard PicoMite).
I have one arrangement that is multi-drop serial where I continuously poll four PicoMites @921600 BAUD, no delays in the code and it works reliably.
lizby Guru Joined: 17/05/2016 Location: United StatesPosts: 3559
Posted: 04:34pm 09 Jun 2025
I'm with Phenix--MMBasic serial is rock solid. If LOC(#1) is greater than 0, you can read bytes.
I think there are two things wrong with your loop--you are not adding what you read to g$, and you're looping UNTIL LOC(#1) = 0 instead of DO WHILE LOC(#1) > 0. Try this:
g$="" If LOC(#1) > 0 then DO WHILE LOC(#1) > 0 g$=g$+input$(LOC(#1),#1) PAUSE 10 ' allow time for more bytes to arrive if they are coming LOOP endif print g$
(But make sure you don't send more than 255 bytes so you don't overrun g$.)
(You can omit the IF ... ENDIF, but it may make it more clear that this block handles serial input when new input has been detected.)
~ Edited 2025-06-10 07:16 by lizby
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2940
Posted: 02:01am 10 Jun 2025
A simple test between 2 PicoMites.
'Pico A GP0 pin1 -------> Pico B GP1 pin2 ' Gnd pin3 -------> Gnd pin3 ' Serial Tx test program on Pico A setpin gp1,gp0, com1 : OPEN "COM1:115200" AS #1 dt$=datetime$(now) do do while datetime$(now) = dt$ : loop 'wait for time to change
print #1, datetime$(now) 'send it dt$ = datetime$(now) loop
' Serial Rx test program on Pico B SetPin gp1,gp0, com1 : Open "COM1:115200" As #1 g$ = Input$(255,#1) : g$="" 'purge the Rx buffer Do Do While Loc(#1) = 0 : Loop 'wait for data to start arriving
Pause 2 'allow time for the rest if the message to arrive 'increase for longer message or lower baud rate Print Loc(#1); " Bytes in Rx buffer", g$ = Input$(255,#1) Print g$; Loop
Output
> RUN 21 Bytes in Rx buffer 10-06-2025 13:05:37 21 Bytes in Rx buffer 10-06-2025 13:05:38 21 Bytes in Rx buffer 10-06-2025 13:05:39 21 Bytes in Rx buffer 10-06-2025 13:05:40 21 Bytes in Rx buffer 10-06-2025 13:05:41 21 Bytes in Rx buffer 10-06-2025 13:05:42 21 Bytes in Rx buffer 10-06-2025 13:05:43 >
Edited 2025-06-10 13:08 by phil99
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6433
Posted: 03:16am 10 Jun 2025
One example where I send a command and wait for a reply. Using GP1 and GP0
' SETPIN GP1,GP0,COM1 OPEN "COM1: 19200" AS #3 ...
FUNCTION sendData$(txt$) LOCAL echo$, n PRINT #3, txt$; PAUSE 30 echo$ = INPUT$(200,#3) sendData$ = MID$(echo$,LEN(txt$)+1) 'for n = 1 to len(echo$) 'print hex$(asc(mid$(echo$,n,1)),2); 'next n 'print END FUNCTION
I notice that you used Data$ as a variable. I am not comfortable using keywords as variable names but you can get away with it sometimes.
Jim
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9841
Posted: 06:47am 10 Jun 2025
That's pretty fast. I'm not sure that MMBASIC is being given enough time to process things, if it's only allowed 10mS to do any processing, before the next 50 bytes arrive....if you see what I am getting at.
Serial is rock-solid, cos I use it all the time in my stuff too, but you have to have enough time for the data to be processed BEFORE expecting the next packet, and 10mS ain't much time at all.
Does the sender also send an end-of-packet byte as part of each packet? That way, you can read the data from the buffer, and stop when you detect the EOP byte, process what is required, and then return to the main loop.
While that is going on, the serial input buffer will continue to buffer any data received, then you just rinse and repeat forever, or until the buffer is empty. Edited 2025-06-10 16:48 by Grogster
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 1693
Posted: 07:19am 10 Jun 2025
Example of my multi-drop:
I always use binary (BIN2STR, STR2BIN) I always have a header &HAA (&b1010 1010)
I don't like using PAUSE, prefer to look for single characters and process them immediately.
do
if loc(2) then b1 = asc(input$(1,2)) if b1=&haa then 'header byte do:loop until loc(2) b1 = asc(input$(1,2)) if b1 = addr then 'is it my address byte? 'You talkin to me? accum="" for i = 1 to 8 'always 8 bytes of data do:loop until loc(2) accum = accum + input$(1,2) next myvalue = str2bin(int64,accum,big) do:loop until loc(2) checksum = asc(input$(1,2)) end if end if end if
loop
Obviously, this could freeze but that would mean a serious problem and watchdog would happen.
@Grogster: I think that, conservatively, 10ms = 1000 lines of execution(?)
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 5619
Posted: 08:26pm 10 Jun 2025
Hi George,
The problem is that you read 100 characters at a time. Let's assume at a certain moment there are 105 characters in the UART buffer. You read 100 (leaving 5) so LOC(#1) equals 5.
It loops, and you read 100. But there are only 5 in the buffer. So it waits until it gets 100 characters, potentially eating 95 characters of the new message.
Volhout
P.S. 50 characters every 10ms. What is your plan to do with them. MMBasic is fast (50.000 - 100.000 instructions per second), but that is still a lot of data for interpreted basic. In my morse decoder program I read 32 values every 10ms and do some fft processing, but that has close to 50% CPU power. I am still puzzling how to translate the fft output into characters fast enough. Maybe using lookup tables. Edited 2025-06-11 06:35 by Volhout
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6433
Posted: 10:12pm 10 Jun 2025
INPUT$() reads upto the given number and will return immediately with whatever there is. It does NOT wait. Looping until LOC() = 0 is OK and a fast way to flush the buffer.
Jim
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9841
Posted: 11:10pm 10 Jun 2025
OK then. I guess I am still thinking in terms of old BASIC interpreters which were very slow compared to MMBASIC.
aFox Senior Member Joined: 28/02/2023 Location: GermanyPosts: 109
Posted: 01:08am 11 Jun 2025
Maybe try to increase the receive buffer size within the OPEN command.
Gregor
Volhout Guru Joined: 05/03/2018 Location: NetherlandsPosts: 5619
Posted: 06:54am 11 Jun 2025
Thanks Jim, for correcting me. I didn't know it would return immediately. So why the DO LOOP. If you have a 256 buffer, why not use input$(255,#1)
Volhout
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6433
Posted: 07:13am 11 Jun 2025
So why the DO LOOP. If you have a 256 buffer, why not use input$(255,#1) Volhout
With a 256 byte buffer you need two reads. Normally I would have a larger buffer hence the do:loop
Once flushed, I use whatever size read is needed for the incoming data with plenty of room to synchronize the stream.