0

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.

3
  • Your Arduino code is fairly complex. Can you write a simple diagnostic sketch to receive serial data? It looks like you are just sending the received data back to the Raspberry Pi, but the Python script isn't even looking for it. Where do you expect the Serial.println() data to appear? Commented Oct 10, 2021 at 15:37
  • recvWithEndMarker seems wrong. It assumes all the message is instantly available in the serial buffer which is unlikely as each character will take over a millisecond to receive.
    – joan
    Commented Oct 10, 2021 at 18:04
  • @ElliotAlderson Just look at recvWithEndMarker() and showNewData() 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. Commented Oct 11, 2021 at 1:33

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.