I'm running some code on Arduino, I have website with a slider which uses a cgi script to pass values to Python. Then the python script uses pySerial to send the values to Arduino which controls a motor.
The plan was to be able to control the motor speed using the slider on the website.
However I seem to be coming up against a problem of the Arduino resetting whenever I change a value on the website, causing the motor to stop. Is there any way around this? My python code is below.
#!/usr/bin/env python
import cgi
form=cgi.FieldStorage()
import json
ser = serial.Serial('dev/ttyACM0', 9600)
#I think there should be a sleep here for 1.5 seconds
ser.write("%s\n" % (form["value"]))
ser.close()
print "Content-type: application/json"
print
print(json.JSONEncoder().encode({"status":"ok"}))
So, say I have the motor running at 50% speed, then change a value on the website, it runs this script which executes the serial.Serial('dev/ttyACM0', 9600) command. That opens the port which resets the arduino, stopping the motor before passing the new command.
Is there any way to pass ser.write("%s\n" % (form["value"])) to the arduino without freshly opening the port? Such as leaving the port open between python sessions?
If not, is there any other way around this problem?
I believe the reset is due to a hardware design of the specific Arduino device you are using. I suggest using an Arduino Micro or Leonardo board instead. They use a virtual serial port and should not restart your sketch each time a serial port is opened. This is from the Arduino site:
No reset when you open the serial port.
Unlike the Arduino Uno, the Leonardo and Micro won't restart your
sketch when you open a serial port on the computer. That means you
won't see serial data that's already been sent to the computer by the
board, including, for example, most data sent in the setup() function.
Serial re-enumeration on reset.
Since the boards do not have a dedicated chip to handle serial
communication, it means that the serial port is virtual -- it's a
software routine, both on your operating system, and on the board
itself. Just as your computer creates an instance of the serial port
driver when you plug in any Arduino, the Leonardo/Micro creates a
serial instance whenever it runs its bootloader. The board is an
instance of USB's Connected Device Class (CDC) driver. This means that
every time you reset the board, the USB serial connection will be
broken and re-established. The board will disappear from the list of
serial ports, and the list will re-enumerate. Any program that has an
open serial connection to the Leonardo will lose its connection. This
is in contrast to the Arduino Uno, with which you can reset the main
processor (the ATmega328P) without closing the USB connection (which
is maintained by the secondary ATmega8U2 or ATmega16U2 processor).
This difference has implications for driver installation, uploading,
and communication...
I you might be able to use the setDTR(False), but I have tested this yet. A while back they fixed the bug that were initially associated with setDTR. What operating system are you use this on?
ser = serial.Serial('dev/ttyACM0', 9600)
ser.timeout = 1
ser.setDTR(False)
Let us know if this does not work.
Related
I have a program written in Visual Basic (.NET Framework 3.0) that communicates with a power supply via a D2XX driver (over COM3) and a pump via a VCP driver (over COM2). Currently, if both USB devices are plugged in when I start the program, it tries to communicate with the pump, (COM2) when trying to communicate with the power supply (COM3). I found a temporary solution to this issue by only have the power supply connected when starting the program. Then I initialize communication with the power supply, and afterwards plug in the pump; this allows the program to communicate with both separately for the rest of the time running the program. But this process is tedious and I am hoping there is an alternative solution where I can keep both units connected via USB and the computer communicates separately. What is confusing is that this communication issue was not always the case, a week ago it worked without having to disconnect the pump (all drivers are updated, and on the device manager they are listed as their respective COM ports as well) ; I am struggling to find some correlation between what is the underlying issue.
I tried to delete other hidden additional COM ports. I made sure all drivers were updated. When the pump is communicating via the same port as the power supply, and then I try to communicate with the pump, I receive this error:
System.UnauthorizedAccessException
HResult=0x80070005
Message=Access to the port 'COM2' is denied.
Source=<Cannot evaluate the exception source>
StackTrace:
<Cannot evaluate the exception stack trace>
But again, If I start the program with only the power supply plugged in and initialize communication with the power supply, and THEN plug in the pump, this issue is evaded. I hope someone can give some sort of direction at all troubleshooting this issue because I am completely stumped. Thank you!
Most likely your program implicitly relied on the correct enumeration order. If you use devices with an FTDI product with internal flash or with dedicated eeprom, you may be lucky: Many can configured via FT_PROG to be visible only for D2XX and not as VCP. This way you can avoid the problem. Alternatively, you can try to modify your program so that it accesses D2XX first. Make sure to filter out the correct device using device informations. E.g. the serial number or the VID:PID if the device manufacturer has made the effort to aquire its own IDs. Check 3.4 FT_GetDeviceInfoList of D2XX Programmer's Guide for details.
I have an infrared thermometer which operates on a virtual serial port over USB, which I am trying to use on a Linux intel and next on a raspberry Pi. The system did not enumerate a /dev/ttyUSB device.
I found a piece of a solution here :
Cygnal Integrated Products serial port on Linux
I reprogrammed the product_ID and can now see it as /dev/ttyUSB0.
But trying to talk to the thermometer with minicom doesn't work.
minicom keeps saying "disconnected" despite the "9600 8N1" indication.
I must say, I had many attempt to work with this kind of communication over USB/serial adapter trying using many different terminal emulator like screen or minicom but without any success at all !
I'm not even sure about the right way to send request and receive data.
Here is the documentation I'm using trying to talk to the thermometer :
http://www.optris.com/interfaces?file=tl_files/downloads/Manuals/addendums-de-en/ct-ctlaser-commands.pdf
Edit :
I'm now trying to use PySerial Python library in a Python script with an Arduino as a target (to act as my thermometer, the arduino runs a simple code that takes the data received and send them back to my Python console.) But still, there is so many confusion possible between ASCII, Hexa, binary, that I'm not capable of debugging anything as I don't know where the transformation between different format takes place !
The communication is working as I can get some data forth and back from my Python console through the Arduino. But I can't get sending hexadecimal data and getting any response back in hexadecimal format. + You say "Your latest question puts you in the off-topic category. ", what do you mean ? Sorry of being so confused.
I use MBED (online IDE & libraries) for my application with host board NUCLEO-411RE and 4D Systems touch display connected by full duplex serial communication.
I am able to send data successfully from host to display without errors. However when sending data from display back to host I am losing data.
Reducing baud to 9600 does not solve the problem.
The host processor remains in a super loop with the first action to check if LCD sends serial data ( lcd4d.readable() ).
Host then receives one character at a time ( lcd4D.getc() ), echos it to the PC via usb ( pc.printf(&recChar) ) and does some further processing.
I am also monitoring the physical host receive pin on a separate terminal session. Using this I am certain that the LCD sends data correctly, however this data is not received and echoed correctly by the host processor (echo to PC is only used for debugging purposes).
Refer to super loop code snippet:
do {
if ( lcd4D.readable() ) {
recChar = lcd4D.getc();
pc.printf(&recChar);
lcd4D_intr_Rx();
}
Also refer to attached screen print showing terminal left PC echo (data loss) and terminal right hardware pin monitor (confirming data sent correctly).
Implementing SerialRX interrupt also does not help the situation with data loss still occurring.
Thanks for any suggestions; I am out of ideas.
I have solved the problem.
The issue was that the host processor needed to respond fast enough to the serial data received. I basically implemented a fast serial receive buffer and ensured that received characters are buffered immediately upon interrupt.
I'm playing around with an old Trackball I purchased from Sparkfun. My trackball powers on, but it doesn't actually work. All the lights flash, and it indicates that I've left and right clicked, but the mouse on my screen does nothing.
I want to monitor the input values of the trackball across a USB port so I can track down the problem. I've looked for code I can run on Netbeans, but came up empty handed.
Please advise
You didn't specified what OS are you using. You need dedicated driver for this device. In case of Linux you would need to write your own driver for the kernel. But first you need to have specification of protocol which this device is using over usb and also usb protocol itself. It is quite sophisticated task to do...
In case of Windows there are some programs for dumping transmission between usb host (PC) and device (trackball), but at the moment I can't give you any name of such program. In case of Linux you can dump the transmission using tcpdump or wireshark commands.
I need to make a program that would play a sound as I press a push button switch. My idea is to use the USB port, and that if I short 2 wires from it (like for example the data+ and data-), the program would play a sound repeatedly while the 2 wires are shorted. Is my idea possible and simple to do? Can you please help me do it using VB? Thanks a lot for any help.
No, that is not practical. USB ports do not have that feature is far as I know. There are plenty of small, cheap USB microcontroller boards that are up to the task though.
For example, you could get an A-Star 32U4 Micro, program it using the Arduino IDE, and make it send a certain message on the its virtual COM port (which is accessed from the Serial object) when a button is pressed and another message when it is released. Then in Visual Basc, you would use the SerialPort class to connect to the A-Star's COM port and listen for that message.
USB ports are mainly used for transmitter and receiver communications for data transfers. They are not used for open or closed switch detection. In order to use a USB port for switch detection, you can used a serial to USB conversion breakout board with a specialized IC chip designed to detect an open or closed switch and communicate this via the USB protocols to send out a communications data transmission that a switch has just been open or closed. Then you would program an application in any language to listen on that USB port for this specific data transmission for a closed or open thrown switch. You can potentially detect about 4 switches opened or closed simultaneously if you want. And this serial to USB breakout board can easily be purchased online at:
https://www.sparkfun.com/products/199