Последовательная связь ПК с Arduino с использованием C и отправка через NRF

Я пытаюсь соединить свой компьютер с Arduino Mega через последовательный порт, а затем отправить сообщение через NRF другому Arduino.

Но я не знаю, правильно ли отправлено сообщение или вообще отправлено ли оно. Потому что я не могу отлаживать с помощью Serial Monitor. Если он открыт, последовательный порт отображается как занятый.

Когда я выполняю код, индикатор TX на Arduino мигает, но через NRF ничего не отправляется.

Я провел несколько тестов, используя только NRF между Arduino, и он работает, но когда я пытаюсь использовать последовательную связь между ПК и Arduino, ничего не происходит.

Код C

#include <stdio.h>
#include <string.h>

char arduinoPort[] = "/dev/ttyACM0";

int main() {

  char buffer[] = {'1'};
  int error = 10;
  FILE *usb_port;

  usb_port = fopen(arduinoPort, "rwb");

  if(!usb_port) {
    perror(arduinoPort);
    return 1;
  }

  //memcpy(buffer, &error, sizeof(error));
  fwrite(buffer, sizeof(char), sizeof(buffer), usb_port);

  fclose(usb_port);

  return 0;
}

Код Arduino

#include <nRF24L01.h>
#include <RF24.h>
#include <printf.h>
#include <RF24_config.h>

RF24 radio(7, 8); // CE, CSN

uint64_t address = 0xF0F0F0F0E1LL;

void setup() {
  Serial.begin(9600);
  printf_begin();

  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
  radio.printDetails();


}

void loop() {

  if(Serial.available() > 0) {

    char byteLido = Serial.read();

    radio.write(&byteLido, sizeof(byteLido));
    delay(1000);
  }
}

, 👍0

Обсуждение

Установили ли вы stty /dev/ttyACM0 правильную скорость передачи данных?, @Edgar Bonet

хм.. я не знаю, как это сделать в коде C, @Shinforinpola

не могли бы вы дать мне несколько советов о том, как это сделать?, @Shinforinpola

Сначала попробуйте из командной строки, просто чтобы убедиться, что это действительно проблема., @Edgar Bonet

Извините, а как это сделать из командной строки?, @Shinforinpola

stty -F /dev/ttyACM0 необработанный -echo 9600, @Edgar Bonet

на терминале ничего не отображается, но индикатор TX некоторое время горит, @Shinforinpola


1 ответ


Лучший ответ:

1

Работа с серийным номером в C в Linux не так проста, как открытие файла и чтение из него (хотя в некоторых обстоятельствах это может сработать).

Вы должны открыть файл, используя open(), а не fopen(), затем используйте tcgetattr() и tcsetattr() и т. д., чтобы настроить порт.

Например:

#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>

struct termios oldsettings, newsettings;
int fd;

// Этот обработчик сигнала аккуратно закроет порт, оставив
// он в том же состоянии, в котором был запущен
void sighandler(int sig) {
    if (sig == SIGINT) {
        if (fd >= 0) {
            // Восстанавливаем настройки к исходным
            tcsetattr(fd, TCSANOW, &oldsettings);

            // Закрыть порт
            close(fd);

            printf("Program teminated. Thank you for playing.\n");
            // Выход из программы
            exit(0);
        }
    }
}

int main(int argc, char *argv) {

    // Ловушка CTRL-C, чтобы правильно закрыть порт
    signal(SIGINT, &sighandler);

    fd = open("/dev/ttyACM0", O_RDWR);
    if (fd < 0) {
        fprintf(stderr, "Error opening serial port: %s\n", strerror(errno));
        return 10;
    }

    // Сохраняем настройки
    tcgetattr(fd, &oldsettings);
    // Снова берем текущие настройки для изменения
    tcgetattr(fd, &newsettings);

    // Установить скорость передачи данных
    cfsetispeed(&newsettings, B9600);
    cfsetospeed(&newsettings, B9600);

    // Делаем его необработанным портом
    cfmakeraw(&newsettings);

    // Применяем настройки
    tcsetattr(fd, TCSANOW, &newsettings);

    char c;
    printf("Press CTRL-C to terminate\n");

    while (read(fd, &c, 1) == 1) {
        printf("Got character 0x%02x\n", c);
    }

    fprintf(stderr, "Reception terminated: %s\n", strerror(errno));

    return 0;
}

Никто никогда не говорил, что программировать на C легко. Это заставляет вас оценить, как много работы API Arduino делает для вас за кулисами...

Также следует помнить, что Arduino сбрасывается (если вы используете Uno, Mega или другую плату с отдельным чипом интерфейса USB) при открытии последовательного порта. Вам нужно подождать около 2 секунд после открытия порта, прежде чем что-либо отправить, иначе все, что вы отправляете, будет полностью проигнорировано. Вы можете сделать это с помощью:

sleep(2);

после того, как вы открыли и настроили порт.

,

Большое спасибо!, @Shinforinpola