Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 10:59 01 Aug 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 : bash -> arduino

Author Message
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5089
Posted: 10:53am 06 Jun 2020
Copy link to clipboard 
Print this post

I could use some help on how to do things in bash...

First some background info...

I am using Putty as a terminal (linux) to control micromites and arduino's through serial port (either /dev/ttyUSBx or /dev/ttyACMx).

On arduino's (UNO) I have a tinybasic interpreter running that allows setting digital outputs and read inputs, mainly because you can buy arduino shield cheap, and can build a "stupid" peripheral cheap. The interpreter can run programs, but can also directly execute command line commands. And that is exactly what is used here.

But this question is not about the interpreter, or the Arduino.

It is about sending data to a serial port from bash (linux shell).

For a quick test project at work I decided to write some expect scripts (dialog) for a simple test setup, controlling the I/O through the arduino. Basically I send strings to serial port, which the arduino processes, and ignore the feedback (the basic interpreter sends a prompt after completion of the command.)

This works "unreliable" at best, and I want to find out why.

#!/bin/bash

#open serial port to arduino
#sudo stty -F /dev/ttyUSB0 9600 cs8 -parenb -cread -crtscts clocal -hupcl
sudo stty -F /dev/ttyUSB0 9600 -hupcl

#let arduino wake up
sleep 5

for i in {1..1000}
do
echo $i
echo "dwrite 13,1" > /dev/ttyUSB0
sleep 0.5
  echo "dwrite 13,0" > /dev/ttyUSB0
sleep 0.5
done


This is basically the script that shows what I am trying to do. Very simplified, just the basics. Pulse output 13 of the arduino.
I have been trying to open the serial port with all kinds of options, but none make it work reliable.

But... when I open Putty with 9600 baud on /dev/ttyUSB0 all works brilliant. I know Putty and my script both access the same serial port.

But Putty does something to the serial port that makes it work. And I can't find out what that is. Even when I close Putty again, it keeps working great.
Even if I shut down the script, and restart it all is fine. Until I reboot the system (in my case a Pi 4 running raspbian).

Is there anyone that has any experience with things like this. Sending serial data to a slave from command line in linux.?
PicomiteVGA PETSCII ROBOTS
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3378
Posted: 11:32am 06 Jun 2020
Copy link to clipboard 
Print this post

For what it's worth (perhaps not much), your combination of stty and echo ... >/dev/ttyUSB0 looks just like what I have used many times for many years--but I've never used an arduino as a target.

I see that in one instance I specified the full path: /usr/bin/stty

I have encountered very obscure (to me) differences between running a command at the prompt and running the same command in a script.
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
SimpleSafeName

Guru

Joined: 28/07/2019
Location: United States
Posts: 351
Posted: 12:04pm 06 Jun 2020
Copy link to clipboard 
Print this post

Just off of the top of my head, I believe that you want to become a member of the "dialout" group (allowing user access to your serial port.

https://askubuntu.com/questions/112568/how-do-i-allow-a-non-default-user-to-use-serial-device-ttyusb0
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 12:26pm 06 Jun 2020
Copy link to clipboard 
Print this post

It may be due to the many opens.

This might help, though it doesn't help that the device has already been opened and closed by the stty.


for i in {1..1000}
do
echo $i >/dev/tty
echo "dwrite 13,1"
sleep 0.5
 echo "dwrite 13,0"
sleep 0.5
done >/dev/ttyUSB0


Sorry if you need parens (*) to use a subshell.

(*) around the whole for loop.

I've had to change the echo $i to compensate for otherwise using ttyUSB0.

There are cunning (?) ways to use redirection to tweak this but see if it helps at all.
BTW, sleep used to need an integer but a float now seems OK.

I'm wondering why you need sudo, as you appear to have permissions anyway.  (Yes, commonly via dialout or the like.)

John
Edited 2020-06-06 22:27 by JohnS
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2442
Posted: 01:07pm 06 Jun 2020
Copy link to clipboard 
Print this post

try adding to the stty line:

[-]clocal
             disable modem control signals


cheers,
rob   :-)
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5089
Posted: 08:32am 07 Jun 2020
Copy link to clipboard 
Print this post

Thank you all for helping me with suggestions.
I tried each one of them and had not the success I hoped for.
But JohnS's suggestion made me think about processes.

I found a working solution, not by tweaking the stty command, or the opening and closing of the serial port, but by simply opening putty in the background (something I did manual to make it work). I don't even have to use the stty anymore since Putty has taken care of that.

So... this works....

#!/bin/bash

#open serial port using pre configured Putty in the background
putty -load "Arduino" &

#let arduino wake up
sleep 3

for i in {1..1000}
do
echo $i
echo "dwrite 13,1" > /dev/ttyUSB0
sleep 0.5
  echo "dwrite 13,0" > /dev/ttyUSB0
sleep 0.5
done


Thank you all for your help, it was your suggestiions that lead to a solution.
It may not be a "production solution" but for my test setup it is fine.

Regards,

Volhout.
PicomiteVGA PETSCII ROBOTS
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025