Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 05:14 12 Jun 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : serial input

     Page 1 of 2    
Author Message
georgestheking
Newbie

Joined: 21/12/2021
Location: Belgium
Posts: 32
Posted: 10:18am 09 Jun 2025
Copy link to clipboard 
Print this post

Hi,

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: Australia
Posts: 2535
Posted: 10:38am 09 Jun 2025
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 2162
Posted: 11:05am 09 Jun 2025
Copy link to clipboard 
Print this post

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: Australia
Posts: 2535
Posted: 11:07am 09 Jun 2025
Copy link to clipboard 
Print this post

Well spotted, I completely missed that.
 
mozzie
Senior Member

Joined: 15/06/2020
Location: Australia
Posts: 131
Posted: 11:32am 09 Jun 2025
Copy link to clipboard 
Print this post

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.

Regards,
Lyle.
Edited 2025-06-09 21:33 by mozzie
 
georgestheking
Newbie

Joined: 21/12/2021
Location: Belgium
Posts: 32
Posted: 11:53am 09 Jun 2025
Copy link to clipboard 
Print this post

Hi,

Thanks to everybody but I still have the problem.
I forget to say it is a WEBMITE version on the standard PICO 2 W board.

Best regards
Georges
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2162
Posted: 11:57am 09 Jun 2025
Copy link to clipboard 
Print this post

still with that 256?

change it to 255 and report back
 
georgestheking
Newbie

Joined: 21/12/2021
Location: Belgium
Posts: 32
Posted: 12:42pm 09 Jun 2025
Copy link to clipboard 
Print this post

Hi,

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 Kingdom
Posts: 1278
Posted: 02:10pm 09 Jun 2025
Copy link to clipboard 
Print this post

  georgestheking said  

I think it is a timing problem.
Things goes too far.
We can not read datas during datas is coming.



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 States
Posts: 3337
Posted: 04:34pm 09 Jun 2025
Copy link to clipboard 
Print this post

  georgestheking said  We can not read datas during datas is coming.


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
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2535
Posted: 02:01am 10 Jun 2025
Copy link to clipboard 
Print this post

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: Australia
Posts: 6248
Posted: 03:16am 10 Jun 2025
Copy link to clipboard 
Print this post

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
VK7JH
MMedit
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9553
Posted: 06:47am 10 Jun 2025
Copy link to clipboard 
Print this post

  georgestheking said  The sender send 50 bytes every 10 mS.
I use SETTICK to read the serial port every 10 ms.


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
Smoke makes things work. When the smoke gets out, it stops!
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1278
Posted: 07:19am 10 Jun 2025
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 4975
Posted: 08:26pm 10 Jun 2025
Copy link to clipboard 
Print this post

  georgestheking said  
DO
 g$=input$(100,#1)
LOOP UNTIL LOC(#1)=0


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
PicomiteVGA PETSCII ROBOTS
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6248
Posted: 10:12pm 10 Jun 2025
Copy link to clipboard 
Print this post

  Volhout said  
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.


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
VK7JH
MMedit
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9553
Posted: 11:10pm 10 Jun 2025
Copy link to clipboard 
Print this post

  PhenixRising said  @Grogster: I think that, conservatively, 10ms = 1000 lines of execution(?)


OK then.  
I guess I am still thinking in terms of old BASIC interpreters which were very slow compared to MMBASIC.  
Smoke makes things work. When the smoke gets out, it stops!
 
aFox
Senior Member

Joined: 28/02/2023
Location: Germany
Posts: 103
Posted: 01:08am 11 Jun 2025
Copy link to clipboard 
Print this post

Maybe try to increase the receive buffer size within the OPEN command.

Gregor
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 4975
Posted: 06:54am 11 Jun 2025
Copy link to clipboard 
Print this post

  TassyJim said  
  Volhout said  
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.


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


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
PicomiteVGA PETSCII ROBOTS
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6248
Posted: 07:13am 11 Jun 2025
Copy link to clipboard 
Print this post

  Volhout said  
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.
VK7JH
MMedit
 
     Page 1 of 2    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025