I want my HomeAssistant being able to send out RF433. HomeAssistant is hosted on RaspberryPi while the RF433-module is on ArduinoNano.
I am referencing this article with some modification.
How to send and read a string from Raspberry pi to Arduino via serial interface?
I am using Ubuntu instead of RaspberryPi for development. Arduino is connected via the serial interface on /dev/ttyUSB0
. It seems the Python script cannot write the text correctly to Arduino.
Arduino code for RF433:
#define AOK_DOWN "10100011101011101110000001011110000000010000000001000011001100001"
#define AOK_UP "10100011101011101110000001011110000000010000000000001011111110001"
#define TRANSMIT_PIN 13 // We'll use digital 13 for transmitting
#define REPEAT_COMMAND 8 // How many times to repeat the same command: original remotes repeat 8 (multi) or 10 (single) times by default
#define DEBUG false // Do note that if you add serial output during transmit, it will cause delay and commands may fail
// If you wish to use PORTB commands instead of digitalWrite, these are for Arduino Uno digital 13:
#define D13high | 0x20;
#define D13low & 0xDF;
// Timings in microseconds (us). Get sample count by zooming all the way in to the waveform with Audacity.
// Calculate microseconds with: (samples / sample rate, usually 44100 or 48000) - ~15-20 to compensate for delayMicroseconds overhead.
// Sample counts listed below with a sample rate of 44100 Hz:
#define AOK_AGC1_PULSE 5300 // 234 samples
#define AOK_AGC2_PULSE 530 // 24 samples after the actual AGC bit
#define AOK_RADIO_SILENCE 5030 // 222 samples
#define AOK_PULSE_SHORT 270 // 12 samples
#define AOK_PULSE_LONG 565 // 25 samples, approx. 2 * AOK_PULSE_SHORT
#define AOK_COMMAND_BIT_ARRAY_SIZE 65 // Command bit count
const byte numChars = 32;
char receivedChars[numChars];
boolean newData = false;
void setup() {
Serial.begin(9600);
Serial.flush();
}
void loop() {
recvWithEndMarker();
showNewData();
}
void recvWithEndMarker() {
static byte ndx = 0;
char endMarker = '\n';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
} else {
receivedChars[ndx] = '\0';
ndx = 0;
newData = true;
}
}
}
void showNewData() {
if (newData == true) {
newData = false;
Serial.println(receivedChars);
if (strcmp(receivedChars, "screen_up") == 0) {
sendAOKCommand(AOK_UP);
} else if (strcmp(receivedChars, "screen_down") == 0) {
sendAOKCommand(AOK_DOWN);
}
}
}
void sendAOKCommand(char* command) {
if (command == NULL) {
errorLog("sendAOKCommand(): Command array pointer was NULL, cannot continue.");
return;
}
// Prepare for transmitting and check for validity
pinMode(TRANSMIT_PIN, OUTPUT); // Prepare the digital pin for output
if (strlen(command) < AOK_COMMAND_BIT_ARRAY_SIZE) {
errorLog("sendAOKCommand(): Invalid command (too short), cannot continue.");
return;
}
if (strlen(command) > AOK_COMMAND_BIT_ARRAY_SIZE) {
errorLog("sendAOKCommand(): Invalid command (too long), cannot continue.");
return;
}
// Repeat the command:
for (int i = 0; i < REPEAT_COMMAND; i++) {
doAOKTribitSend(command);
}
// Disable output to transmitter to prevent interference with
// other devices. Otherwise the transmitter will keep on transmitting,
// disrupting most appliances operating on the 433.92MHz band:
digitalWrite(TRANSMIT_PIN, LOW);
}
void doAOKTribitSend(char* command) {
// Starting (AGC) bits:
transmitHigh(AOK_AGC1_PULSE);
transmitLow(AOK_AGC2_PULSE);
// Transmit command:
for (int i = 0; i < AOK_COMMAND_BIT_ARRAY_SIZE; i++) {
// If current bit is 0, transmit HIGH-LOW-LOW (100):
if (command[i] == '0') {
transmitHigh(AOK_PULSE_SHORT);
transmitLow(AOK_PULSE_LONG);
}
// If current bit is 1, transmit HIGH-HIGH-LOW (110):
if (command[i] == '1') {
transmitHigh(AOK_PULSE_LONG);
transmitLow(AOK_PULSE_SHORT);
}
}
// Radio silence at the end.
// It's better to go a bit over than under minimum required length:
transmitLow(AOK_RADIO_SILENCE);
if (DEBUG) {
Serial.println();
Serial.print("Transmitted ");
Serial.print(AOK_COMMAND_BIT_ARRAY_SIZE);
Serial.println(" bits.");
Serial.println();
}
}
void transmitHigh(int delay_microseconds) {
digitalWrite(TRANSMIT_PIN, HIGH);
//PORTB = PORTB D13high; // If you wish to use faster PORTB calls instead
delayMicroseconds(delay_microseconds);
}
void transmitLow(int delay_microseconds) {
digitalWrite(TRANSMIT_PIN, LOW);
//PORTB = PORTB D13low; // If you wish to use faster PORTB calls instead
delayMicroseconds(delay_microseconds);
}
void errorLog(String message) {
Serial.println(message);
}
Python code (to be run on Raspberry Pi) to trigger Arduino:
import serial
ser = serial.Serial('/dev/ttyUSB0', 9600)
ser.write("screen_up\n".encode("utf-8"))
ser.close()
May anyone point out my problem please? Thanks.
recvWithEndMarker()
andshowNewData()
please. The rest of the code is used to control RF433. I want the Arduino code to wait for "instruction" from the Python code and then send the RF433 signal respectively.