Zero cross detection with serial communication from Arduino to Raspberry Pi - raspberry-pi3

I'm new at python and i'm setting up my school project that it's going to detect the zero cross for trigger a PWM pulse so i'm using Arduino and Raspberry Pi 3.
I'm trying to read from serial port of the Arduino for read it in the Raspberry Pi, after that what i need is build an if conditional with that data that i recieved.
Arduino sends from serial port ON and OFF message with this code
const int inputPin = 2;
int value = 0;
void setup() {
Serial.begin(9600);
pinMode(inputPin, INPUT_PULLUP);
}
void loop(){
value = digitalRead(inputPin); //digital read of pin
//sends a message to serial port depending of the value read
if (value == HIGH) {
Serial.println("ON");
}
else {
Serial.println("OFF");
}
delayMicroseconds(1000);
}
On Arduino serial read it shows continuously
OFF
ON
ON
ON
OFF
So on python i want to read those two values "ON" and "OFF" or at least one that when it takes a OFF value for example at the next 1 ms it turn on PWM pulse.
Something like:
if zerocross == OFF:
pi.hardware_PWM(heat,200,dutycycle)
This is my python code for read the data from serial port:
import time
try:
import serial
arduino = serial.Serial('/dev/ttyACM0', baudrate=9600, timeout=1.0)
arduino.setDTR(False)
time.sleep(1)
arduino.flushInput()
arduino.setDTR(True)
except (ImportError, serial.SerialException):
import io
class FakeArduino(io.RawIOBase):
def readline(self):
time.sleep(0.1)
return b'sensor = 0\toutput = 0\r\n'
arduino = FakeArduino()
with arduino:
while True:
try:
line = arduino.readline()
zerocross = line.decode('ascii', errors='replace')#, end=''
if zerocross == OFF:
print ('ok')
except KeyboardInterrupt:
print("Exiting")
break
this is the out in the python shell
Traceback (most recent call last):
File "/home/pi/Desktop/arduino python raspb.py", line 33, in <module>
if zerocross == OFF:
NameError: name 'OFF' is not defined
I've already tried to convert the serial data into a string but i get "built-in method decode" when i try to print the value. Please if someone can show me some other methods i would appreciate it so much.

Related

How to send AT commands to ESP32 LilyGo-T-Call-SIM800?

I've been working with a LilyGo-TCall-SIM800 module for several days, trying to get out of a dead end.
I have tried an example from "random nerd tutorials" which works correctly. The module connects to the internet and can send data to the cloud.
I have the problem to send AT commands to the SIM800L chip integrated in the module. I can't get the chip to react back.
I have tried using Serial1 and Serial2. I have also tried configuring the RX and TX transmission pins, and I have tried with different baudrates. Always with negative results... when sending the "AT\r" command to the SIM800L, it should return "OK". But it never does.
I have simplified the code as much as possible to minimize errors:
/*
Name: TestAT.ino
Created: 08/12/2022 23:15:28
Author: user
*/
// Set serial for debug console (to the Serial Monitor, speed 115200)
#define SerialMon Serial
// Comunications between ESP32 and SIM800L
#define SerialAT Serial1
//Comunications between ESP32 ans SIM800L go thought TX and RX pins on Serial1 Port
#define MODEM_RX1 16
#define MODEM_TX1 17
void setup() {
// Set console baud rate
SerialMon.begin(115200);
delay(1000);
//Set SerialAT baud rate
SerialAT.begin(38400, SERIAL_8N1, MODEM_RX1, MODEM_TX1);
//Set timeLimit for SerialAT reads
SerialAT.setTimeout(2000);
}
void loop() {
String returned = "";
char ATcommand[] = { 'A','T','\r' };
SerialAT.print(ATcommand);
delay(1000);
returned = SerialAT.readString();
SerialMon.print(millis());
SerialMon.print(" - ");
SerialMon.print(ATcommand);
SerialMon.print(" - SerialAT returned:");
SerialMon.println(returned);
}
Anybody can help me out on this? Any idea or sugestion?
Thanks in advance

UART program for PIC18f65k40

I'm trying to program my MCU in mickroc still I do not get a output.
Is there any difference between PIC18f65k40 and PIC18f65k22 in terms of initiating uart transmission? Whether there is any need to initiate or disable any special registers in PIC18f65k40?
In mikroc software there present a library for uart so I just copied the program from mickroe website and add my transmitter and receiver pins(RX4PPS = 0x11; and TX4PPS = 0x10;)in program by configuring portc as output but my circuit does not work.
char i ;
void main()
{
TRISC = 0b00000000;// making port as output
RX4PPS = 0x11;
TX4PPS = 0x10;
UART4_Init(9600); // Initialize USART module
// (8 bit, 9600 baud rate, no parity bit...)
delay_ms(500);
UART4_Write_Text("Hello world!");
UART4_Write(13); // Start a new line
UART4_Write(10);
UART4_Write_Text("PIC18F65K40 UART example");
UART4_Write(13); // Start a new line
UART4_Write(10);
while (1) {
if (UART4_Data_Ready()) { // If data has been received
i = UART4_Read(); // read it
UART4_Write(i); // and send it back
}
}
}
The PIC18F65k22 has only 2 UARTs and you are working with UART4. I guess the library don't support the controller. Better write the code on your own. There are some examples in the datasheet.

arduino + serialport communication + ruby

I'm trying to turn on an LED connected to an Arduino from a ruby file, as well as sending a string from that Arduino to my ruby file / terminal. (I'm doing these two things separately, to avoid potential problems).
I'm using a USB port to connect Arduino - Computer, and the serialport gem. I'm working in Linux.
To receive the string on my computer:
I have followed several tutorials that all recommend to run this ruby file:
require 'serialport'
port_str = '/dev/ttyACM0'
baud_rate = 9600
data_bits = 8
stop_bits = 1
parity = SerialPort::NONE
sp = SerialPort.new(port_str, baud_rate, data_bits, stop_bits, parity)
while(true) do
message = sp.gets.chomp
puts message
end
And uploaded this to the Arduino:
uint8_t c;
int i;
void setup() {
Serial.begin(9600); // set baud rate
pinMode(13, OUTPUT); // set pin 13 to be output for LED
digitalWrite(13, LOW); // start with LED off
}
void loop() {
while (Serial.available() > 0) { // check if serial port has data
// writes to computer
Serial.println("Hello world");
}
}
I got this error message: undefined method `chomp' for nil:NilClass (NoMethodError). When getting rid of .chomp, at some point I could get some parts of "Hello world" being printed on my terminal, such as "Hell", and then far later "o w", etc.
Now I don't even get anything anymore.
To turn the led on:
In the ruby file, I replaced the message part by
sp.write('a')
And in the arduino file,
void loop() {
while (Serial.available() > 0) { // check if serial port has data
c = Serial.read(); // read the byte
if (c == 'a'){
digitalWrite(13, HIGH); // turn on LED
delay(500); // wait 500 milliseconds
digitalWrite(13, LOW); // turn off LED
delay(500); // wait 500 milliseconds
}
}
}
The led turns on if I remove the condition (c == 'a'), but obviously I need it if I want the arduino to perform different actions.
I'm new to Serial communication, so I'm not quite sure where the error comes from, since I feel somehow some data seems to be transmitted.

Bluetooth Serial Port Permission Error Errno::EACCES [Ruby] [Serialport gem]

So I am trying to send data to my Arduino through a HC-05 Bluetooth Chip. I'm using Ruby, and so far, I get the error shown below. Any idea why? I'm using Windows 10
My arduino is on COM3 (USB) and the bluetooth chip is on COM37
Error 1
in `create': Permission denied - \\.\COM37 (Errno::EACCES)
If I try it again I get this error:
Error 2
in `create': Invalid argument - \\.\COM37 (Errno::EINVAL)
Ruby Code
require 'serialport'
puts "What COM Port?"
comport = gets.chomp
comport = comport.to_i
comport = comport -1
sp = SerialPort.new(comport,9600)
while 1
puts "What message do you want to send?"
write = gets.chomp
if write == "exit"
abort
end
sp.write write
end
Arduino Code
#include <Motor.h>
#include <SoftwareSerial.h>
Motor m8(8);
SoftwareSerial Bluetooth(12, 13); //12-TX 13-RX
// Declare a new 'char' or "character" that we will use to store the keyboard
// input sent to the bluetooth chip
char input;
boolean stop = false;
void setup() {
Bluetooth.begin(9600);
m8.attach();
}
void loop() {
// If there is input available on the bluetooth chip (that is, we sent a character
// to the chip from the computer)...
if (Bluetooth.available()) {
// Read the first available character from the bluetooth chip and store it in the
// 'input' variable
input = Bluetooth.read();
if (input == 'w') {
stop != stop;
}
if (input == 'd') {
m8.turn(100);
}
if (input == 'a') {
m8.turn(-100);
}
}
if (stop != true) {
m8.stop();
}
}
If I try to connect to my arduino using COM3 and USB, I don't get an error and it successfully sends data the the arduino.
Thanks in advance!

Visual Studio 2010 Arduino serial communication

I am using OpenCV in Visual Studio 2010 to track an object, and I am trying to send a value to the Arduino to rotate servos attached to the camera. I am using an Arduino Uno. I have completed the C++ code that tracks the object and determines which direction the camera needs to be rotated, but I am having trouble sending this data to the Arduino. I am currently trying to use an RS-232 cable for this. I am using a Type-B USB cable to program my Arduino and an RS-232 to try to send the data from Visual Studio to the Arduino. Here is my code for the Visual Studio serial communication:
int portspeed(int centerpix, int xmid)
{HANDLE hDevice = CreateFile(L"COM5",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,0);
DCB lpTest;
GetCommState(hDevice,&lpTest);
lpTest.BaudRate = CBR_9600;
lpTest.ByteSize = 8;
lpTest.Parity = NOPARITY;
lpTest.StopBits = ONESTOPBIT;
SetCommState(hDevice,&lpTest);
DWORD btsIO;
if (centerpix<xmid)
{
char test[] = "2";
WriteFile(hDevice,test,strlen(test),&btsIO,NULL);
cout << "Turn right " << test << endl;
}
else
{
char test[] = "3";
WriteFile(hDevice,test,strlen(test),&btsIO,NULL);
cout << "Turn left " << test << endl;
}
return 0;
}
On the Arduino code side I have this, which I am using to attempt to light two different LEDS to see if the program is able to correctly communicate which direction it needs to rotate:
int incomingByte = 0; // For incoming serial data
void setup()
{
Serial.begin(9600); // Opens serial port, sets data rate to 9600 bit/s
}
void loop()
{
// Send data only when you receive data:
if (Serial.available() > 0)
{
incomingByte = Serial.read();
if (incomingByte==50) //if =2
analogWrite(9,100);
else
analogWrite(9,0);
if (incomingByte==51) //if =3
analogWrite(10,50);
else analogWrite(10,0);
delay(3000);
}
else
analogWrite(9,255);
}
My interpretation is that I need to start the C++ program (which continuously sends the data over the serial communication), and then attach the TX pin from the RS-232 into the RX pin (digital 0) on the Arduino. When I try to upload the program to the Arduino I am given an error,
avrdude: stk500_getsync(): not in sync: resp=0x00
This only occurs when I have a wire going into the RX pin, even if this wire is not connected to anything. I believe that this error occurs because the RX is looking for an input with a baud rate of 9600, but it still gives me this error when the C++ program is running and sending the data with a rate of 9600.
How can I send a value from a Visual Studio project doing real time image processing on a laptop to an Arduino via serial communication?
Speaking as someone with limited Win32 experience (more of a .NET guy, really), I think your problem may be in write buffering.
By default, writes to a file or port are buffered in memory. Perhaps the write is never getting sent to the port as you are never closing the file handle nor calling [FlushFileBuffers][3].
Try adding this prior to return 0;:
//After a time, sensitive write
FlushFileBuffers(hDevice);
//or, more properly for the end of the program.
CloseHandle(hDevice);

Resources