This has been resolved!!
I have to wait a few seconds after opening serial port.
I want to execute the python program that is being done with the send button on the Arduino serial monitor.
if (Serial.available() > 0){
Serial.print(hoge);
}
is written in arduino, and I want to make Serial.available ()> 0 by python program.
I tried...
1.
If I send something like A or 3 on the IDE serial monitor, the contents of hoge will be output on the serial monitor.
2.
Using pyserial
ser = serial.Serial('/dev/ttyACM0', 115200,timeout=None)
ser.write(str.encode('A'))
data = ser.readline()
print(data)
When this is executed, it waits for reception before ser.read ().
After deleting the if (Serial.available ()> 0) of the program on Arduino and executing it, the contents of hoge were printed properly on the terminal.
The contents of hoge are
b'0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\r\n'
What do I need to write to do the same thing as 'send'? How do I get Serial.available ()> 0 ...?
It would be very helpful if you could tell someone.
The first data of 'hoge[]' is NULL character. Therefore there's no chance for 'Serial.print()' function to print out the whole content.
Serial.print(hoge) immediately returns because the first character is NULL character.
ser.readline() is waiting forever because there's no newline incoming from Arduino.
Simply changing the content will solve this issue or use write() function (but if you keep the same content then you need to adapt your python code as well without using readline()).
In your python code, you need to add "time.sleep()" before "ser.write()" so that Arduino is ready to receive the serial data. More than 1 seconds would be required.
I've coded a simple script for Windows that works fine and I have adapted it to Linux (Ubuntu). The problem is that it doesn't read the byte sent.
I tried all the different serial ports available according to the Arduino IDE but the problem persists.I also used \n and \r without success and different encodings.
Code working on win10:
import serial
import time
import keyboard
arduino = serial.Serial('COM4', 9600, timeout=0)
while True:
arduino.write('a'.encode())
time.sleep(0.1)
print(arduino.readline())
Code not working on Ubuntu:
import serial, time
arduino = serial.Serial('/dev/ttyAMC0', 9600, timeout = 0)
while True:
arduino.write('a'.encode())
time.sleep(0.1)
print(arduino.readline())
So the first script prints continuously a\r\n, the second doesn't. Simply shows b'' continuously. So I think it doesn't simply write the letter.
Solved. No idea what exactly was thr issue but worked sending capital letter.
Im trying to read data from a simple COM3 USB Serial Port with PySerial.
My Code is as follows:
import serial
import time
ser = serial.Serial("COM3", 230400, timeout=2) #Also tried timeout=None, loads to infinity then
print (ser)
while True:
line = ser.readline() #also tried read()
print(line)
time.sleep(1)
Console Outupt:
print(ser)
=>Serial<id=0x2757c50, open=True>(port='COM3', baudrate=230400, bytesize=8, parity='N', stopbits=1, timeout=2, xonxoff=False, rtscts=False, dsrdtr=False)
I tried to mess around with the boolean-attributes of the Serial object ser(e.g. xonxoff) with no success
print(line)
=> empty string or b''
I tried to test this in Python 2.7 and Python 3.6.5.
Listing all COM Ports via serial.tools.list_ports.comports() returns this:
COM3 - USB Serial Port (COM3)
COM46 - com0com - serial port emulator CNCA0 (COM46)
COM47 - com0com - serial port emulator CNCB0 (COM47)
When I use the program HDTerm I get the following output:
Screenshot_HDTerm_COM3_Port_Output
So the Port actually returns something, but I can't read the data from python somehow. The parameters are the same in my Python Code as they are in HDTerm.
Any idea why Python is printing nothing (or loading to infinity if timeout=None)?
PS.: COM46 & COM47 are working perfectly fine in Python and HDTerm. But they have other outputs (sending and receiving data from each other only).
I solved the problem by myself now.
I had to do ser.dtr=False
Even though print(ser)showed that the parameter dsrdtr=False (which I interprete as "dsr and dtr") the attributeset.dtr remained to be True (test with print(set.dtr).
You have to manually set dtr to False as shown above. Seems a bit odd to me, maybe a bugg?
if i get you right.
try
type(ser)
that way you will know the type of 'ser', if it's an iterable(list, tuple,etc...), you can try:
for s in ser:
print s
time.sleep(1)
hope this help.
I'm currently trying to complete all levels on Over the Wire's Bandit 'wargame'.
One of the levels (level 24), requires that I connect to a port, on which a daemon is running. This daemon asks to input a password and a 4-digit pin. The password is already known (it is provided at the end of the previous level), the pin is unknown. The indication is that it's necessary to 'brute-force' it.
Entering a wrong pin results in this message: "Wrong! Please enter the correct pincode. Try again.".
I decided to write a python script that automates the process. The script would:
1) Connect to the port via netcat
2) Enter the password and a randomly generated pin
3) Read the output, and, if the word 'again' is in it (meaning the pin is wrong), repeat via a loop, until the pin is guessed.
But although my script runs and connects, it fails to communicate with the daemon, once the connection to its port is established.
All I get is the daemon's prompt, requesting password and pin.
This is my code:
import subprocess
import random
# Initialise variables
pin = ''
output = "Wrong! Please enter the correct pincode. Try again."
# Connect to the port
def connect_to_port():
subprocess.call(["nc localhost 30002"], shell=True)
# Generate pin
# TO DO: skip pins that were proven incorrect
def generate_pin():
pin = ''
pin_len = 0
while pin_len < 4:
pin += str(random.randint(0, 9))
pin_len += 1
return pin
# Connect to port
# Loop: check if 'again' is in 'output',
# if it is, generate a pin and input password and pin
def main():
connect_to_port()
while 'again' in output:
pin = generate_pin()
out = subprocess.check_output(["UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ", pin])
output = out.decode("utf-8")
main()
I suspect I'm not using the subprocess module correctly, but I can't really understand how. Why is my script not working?
Forgive my rudimentary use of the relevant terminology.
EDIT: I see the use of subprocess.check_out() is all wrong. What I'd need, as suggested in the answers and comments, is to open a PIPE and use communicate() to write to the subprocess's stdin (modifying the pin each time) and read its stdout, but I'm not sure how to go about that.
The netcat needs to be opened once during the conversation and then multiple reads and writes need to be performed.
If you want to be able to read and write data to the subprocess, you will need to create a PIPE so use the Popen interface, then you can use communicate().
Given how trivial this is, why not just open a socket directly in python?
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 30002))
data = sock.recv(64)
sock.send(pin)
I am trying to make a simple python 2.6 application on OSX 10.6.6 that can send and receive SMS on my Zoom 7.2m (3g) USB Modem.
On initially plugging into the USB modem, no TTY or CU sessions seem to be created. I have to run the modem software to initiate the following sessions;
cu.LJADeviceInterface2621
cu.LJADiagConnector2620
cu.LJAMobileConnector2622
tty.LJADeviceInterface2621
tty.LJADiagConnector2620
tty.LJAMobileConnector2622
After much "fun", it seems the only session I can read and write to is "cu.LJADeviceInterface2621". On attempting to connect to the tty instance of this, I get an error -
serial.serialutil.SerialException: could not open port /dev/tty.LJADeviceInterface2621: [Errno 16] Resource busy: '/dev/tty.LJADeviceInterface2621'
Thats fine though - I at least have something to work with, the cu equivalent.
My script is as follows;
ser = serial.Serial("/dev/cu.LJADeviceInterface2621", 9600, timeout=1)
print "Setting DTR..."
ser.setDTR(True)
sleep(3)
print "Turning off DTR..."
ser.setDTR(False)
searching = True
ser.setDTR(True)
while searching:
print "Write instruction..."
txt=raw_input()
if txt.find("ZZ")>-1:
txt=txt.replace("ZZ",chr(13))
ser.write(txt)
ser.close()
Now, I also have another script that is monitoring the messages on "cu.LJADeviceInterface2621". That script is as follows;
ser = serial.Serial("/dev/cu.LJADeviceInterface2621", 9600, timeout=1)
print "Attempting search."
while True:
line = ser.readline()
print ">", line
With these scripts both running, in the WRITE code, I enter the following lines;
(Note: ZZ input is replaced for Ctrl-Z via the write script above - chr(13))
AT+CMGF=1ZZ [press enter to commit write]
OK
AT+CMGW="+447725123123"\r\n [press enter to commit write]
ERROR
I should be writing the text of the message, followed by Ctrl-Z (chr(13) but I get an immediate error.
The USB modem has a valid sim, with credit, it has signal, I can send a text from the Zoom Modem Software (this however only works in with PDU mode - but the modem does support text mode, as per the AT+CMGF=? command) and receive messages.
Any ideas?
Happy to provide more information where needed, thanks
Stu
Also remember that there are many projects out there that do the task for you (pysms is one of them)
Well, I never use that modem but I suppose it uses standard GSM AT commands, and AT+CMGW is wrong.
You should send: AT+CMGS="+111111111"\r\n SMS TEXT Ctrl-Z
And that should work