How do i run a system() command using arduino sketch program? - arduino

So, here is the thing. I have written an arduino sketch program and this is what i want say if the LED blinks then say the following code is executed such as
system("c:\temp\capture.txt") something like that. Is there a way to do that?
void loop()
{
val = digitalRead(2);
if(val == HIGH)
{
digitalWrite(LED,HIGH)
//system command happens here
}
}
How do i do that? Thanks

Arduino won't be able to execute programs in PC directly because its system is isolated from PC. That's why Arduino can run programs without PC (standalone).
Consider developing a host program that run on your PC and accept comnands via serial communication, and send comnand to execute something from Arduino to the host program. Then, have the host program execute the program to run.

Related

Delay in Serial Communication when talking between Arduino and Python

I have an Arduino-controlled robot with a gyroscope, and I'm trying to send data from it over to a Python program run on a Raspberry Pi. However, there's a 1-2 second delay between me moving the robot, and info being printed out the python program. I've tried restarting my computer, as well as replugging the wires. Is there anything I'm doing in my code that is causing this or is it a hardware thing?
The robot is connected to a Raspberry Pi, with which I have a headless setup. The python program is being run on the Pi but can be viewed on my desktop over SSH. The program has no delay when I connect the robot to my desktop and run the python program on it as well.
Arduino Program:
#include <robot's file>
Gyro gyro; //Object using an imported class
void setup() {
Serial.begin(115200);
while (!Serial) {}
}
void loop() {
gyro.read(); //Reads the robot's yaw and puts it into variable "z"
Serial.println(gyro.z);
}
Python Program:
import serial
from serial.serialutil import SerialException
ser = serial.Serial("/dev/ttyACM0", 115200)
try:
ser.open()
except SerialException:
print("Port already opened")
while True: print(ser.readline())
looks to me that everything is good in your code.
Most of the delay is related to your PC computing time.
If you want to speed up the process I would suggest to interface an Oled display (or an LCD) to display directly your data: using your PC is good for the initial testing, but if you need immediate response it is better to manage the data interfacing directly.
This link may support you: https://www.waveshare.com/wiki/1.3inch_OLED_HAT All the best
After some testing, I think I've figured it out.
Printing to terminal takes a long time, which made the Arduino program faster than the Python program, creating a buildup of data, causing the delay. I've fixed the problem by only printing out data every 10 iterations. The problem would also be fixed if I stored the data into a variable, and did not call the print() function.

ESP32 Switch Between Promiscuous and STA Mode

I'm working on a project based on the ESP32 platform. The aim is to count the number of MAC addresses in the area, and transmit this information over WiFi (using an http POST request).
The first task is achieved by sniffing WIFI packets and collecting the contained addresses, following this example: https://blog.podkalicki.com/esp32-wifi-sniffer/
I believe that the code which "sniffs" the packets sets the ESP to run in promiscuous mode, and therefore I cannot connect to any AP anymore.
I've tried several solutions, first starting with timer interrupts. However this approach always led to a Core Panic and reset of the chip.
I also learnt I could use RTOS to run different tasks in parallel on the two cores of the CPU, but that didn't help to solve the problem.
void wifi_sniffer_packet_handler(void* buff, wifi_promiscuous_pkt_type_t type)
{
if (type != WIFI_PKT_MGMT)//aggiungere filtro su RSSI a questa altezza.
return;
const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff;
const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)ppkt->payload;
const wifi_ieee80211_mac_hdr_t *hdr = &ipkt->hdr;
//some analysis and then print the MAC address
}
void setup() {
Serial.begin(115200);
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &chUpdate, true);
timerAlarmWrite(timer, 1000000, true);//timer, arr_val, reload=true
delay(4000);
wifi_sniffer_init();
timerAlarmEnable(timer);
}
// the loop function runs over and over again forever
void loop() {
//Serial.print("inside loop");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Establishing connection to WiFi..");
}
Serial.println("Connected to network");
}
I also noticed that the code in the loop gets stuck into the while, and is restarted every time the packet handler is run (I nevere get to see "Connected to network", but i see "Establishing connection to WiFi.." several times.
Anyone can explain me what's going on? Is there a different approach to achieve this result?
Thank you.
You may have two tasks and two cores, but the ESP32 still has only one wifi chip. The way your code is written (at least, the code you shared), you'll be trying to connect to a wifi network at the same time as you're trying to run promiscuous mode. You can do only one of those things at a time.
You'll need to stop promiscuous mode before you attempt to connect to an access point. Right now your code constantly attempt to connect to a wifi access point. Use a volatile variable to store the current mode - promiscuous or connected. Change it when you need to change states. Only attempt to connect to wifi when the variable says you want to be in connected mode.
There may be some code you need to run to turn off promiscuous mode when you change states, before you connect to a wifi access point.
If you're using wifi_sniffer_init() from the example you linked to, that code isn't meant to be run in an Arduino Core application. It does some network initialization that the Arduino Core will also do. It may not be safe to do that twice (it might work, it might not... but it's definitely not intended to be done that way).
You're setting an interrupt handle chUpdate() which you didn't share. I'd bet that's the cause of your Core Panics. You can do very little in an interrupt handler. You definitely can't call most Arduino Core functions or most ESP-IDF functions. Most code isn't protected against interrupts, so the timer interrupt can occur while data structures are in an inconsistent state. Re-entering code can corrupt the data structures and cause the kind of crash you described. You're best off setting a volatile variable and waking up a task that will do the work you need done while not in the interrupt handler.
Finally, you should call WiFi.mode(WIFI_STA); before you call WiFi.begin().
For anyone confused about why you can't connect to a wifi network while in promiscuous mode - what ESP8266 and ESP32 call "promiscuous mode" is really "wifi monitor mode", which lets you monitor a wifi radio channel and see all wifi frames sent on it. They use the term "promiscuous mode" differently from the rest of the industry. Usually "promiscuous mode" means seeing all the packets being sent on the network (wifi or hardwired) that you're connected to.
I know that it's been just over a year but THANKS to the info provided by romkey I think I solved this problem within my app by calling this routine before connecting to WiFi to upload MAC data.
void end_Scan_WiFi() {
esp_wifi_set_promiscuous(false);
esp_wifi_stop();
}
Followed by this ...
WiFi.mode(WIFI_STA);
WiFi.begin(ssid,pass);

How can I use Process class in Arduino Yun to read some stream-data?

Running shell command through Bridge in Arduino Yun through a Process let's say, proc, it gives result and we can read the result bytes using following piece of code.
#include <Bridge.h>
#include <Process.h>
void setup() {
Bridge.begin();
Serial.begin(9600);
while (!Serial);
}
void loop() {
Process proc;
proc.runShellCommand("ls /root/");
while (proc.available() > 0)
Serial.print((char)proc.read());
Serial.println();
}
What if I have to access data from a blocking shell command as it gets updated like and event? Such as, some consumer that listens to Kafka or Mosquitto subscribed topic. Whenever that topic is updated/published with new data, the listener gets it.
How can I model such structure using Arduino Yun program using Bridge.
You can do it quite easily.
Run that particular command with nohup, in that case, file with the name nohup.out would be created. then after that run a script that continuously monitors that nohup.out file in case of any change in the size of nohup.out, get the latest data and push that data to anywhere you want.

Reading serial data from Arduino fails

I have written a program for Arduino that reads some analog signals and sends them to the computer when it receives a command from the master computer. I wondered why this didn't work on the computer it was intended to run on. On my own computer it runs fine.
I uploaded a simple test code in the Arduino.
void setup() {
Serial.begin(9600);
}
void loop() {
if(Serial.available()) {
Serial.println(Serial.read());
}
}
This doesn't run on the second computer either. When I use Arduino serial monitor for transfering data, I see the RX led blink but not the TX. With the computer it's working on, I can see both of the leds flash. Arduino receives the data on both computers, but the second computer doesn't receive Arduino's responses. What might be wrong?
Edit. I forgot the Arduino hooked up to the problematic PC for a few minutes and tried it again. Then it worked! It seems like it needed some time to warm up. Why's that?
Sometimes it can take a second for the Arduino and computer to establish the Serial handshake, especially at 9600 baud. I'm glad you got it working!

Raspberry Pi w/ Archlinux: C program freezes when writing to serial port

I've got an Arduino attached to my Raspberry Pi which runs on Archlinux ARM, and I'm using a simple C program that reads and writes to the serial bus to the Arduino (/dev/ttyACM0).
This worked fine as long as I had the Arduino attached to my PC, but when I use the Raspberry Pi instead, reading still works but writing will freeze as soon as the buffer is flushed or the connection closed.
This very basic C example atually causes such a freeze:
If the fflush() command is in there it will freeze there, if it's removed then it'll instead freeze at fclose().
FILE *fp;
fp = fopen("/dev/ttyACM0", "wb");
..error handling..
fprintf(fp, "%c", 'B'); /* write the character 'B' to the serial port)
fflush(fp); /* optional, if more write operations follow, in an actual program */
fclose(fp);
Reading from the bus works fine.
I also tried the program "minicom" as it is often suggested for testing serial connections, and it yielded the same results: Sending from Arduino to Pi is fine, trying to type in a character on Pi side -> freeze.
I have tried lots of different stuff on opening/configuring such as replacing the simple fopen() sequence shown above by:
fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY);
fcntl(fd, F_SETFL, 0);
if (fd == -1) {
printf("couldn't open serial port.\n");
return -1;
}
fp = fdopen(fd, "w");
and also changing some canonical something parameters (not sure what I'm actually doing there) but to no avail. It will just keep freezing as soon as the Pi tries to write a character to the serial bus.
I've also made sure that all TTYs are unused on the Pi via
ps -ef | grep -i tty
to exclude any silly getty/agetty interference.
And I've tested it without any additional hardware plugged in, to make sure that it isn't a symptom caused by the power supply not being able to sustain everything connected to the Pi, as someone suggested to me.
By now I'm totally out of ideas except that the hardware is maybe just faulty. But that's hard to believe, is it? (And I don't have a replacement to test.)
UPDATE:
When using above alternate sequence and removing the fcntl() line, the C program no longer freezes on writing:
fd = open("/dev/ttyACM0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
printf("couldn't open serial port.\n");
return -1;
}
fp = fdopen(fd, "w");
So at first I was happy, but actually the written data never arrives on the Arduino side! :(
first of all, rasPI cannot work directy from a PC USB as they are limited below the rasPI need, so you need an external power supply (i used one from a smartphone, now i'm using a plugged usb hub)
Changes are that plugging your arduino drains too much power, and the arduino's and rasPi chip beave randomly. Check if, when the program freeze, the serial port used is still there (check with dmesg, maybe it has been plugged/uplugged)
If your power source are fine, then explain what you mean by freeze; the rasPi freeze or only the code. Eiter case it is a fault on the rasPi side, try updating OS and firmware; the serial does not check if someone is reciving, so flush should only hang the time necessary to write the buffer, even if no one is reading.
remeber that close(), will always call flush(), so use flush() only if really needed. (like in this case, for debugging purpoise :) )

Resources