Взаимодействие между C и Arduino

Я боролся с этой проблемой некоторое время, и это сводит меня с ума:

Я пытаюсь очень просто связаться с Arduino Mega 2560 (через USB в качестве последовательного устройства) с ПК под управлением Linux (Knoppix на USB-док), когда все, что я пытаюсь сделать на этом этапе, это то, что для каждого числа, отправленного ноутбук к Arduino, сигнал «стоба» будет переключаться с высокого на низкий или наоборот, и я использую этот стробоскоп для включения и выключения светодиода.

C-код на стороне ПК:

#include <stdio.h>

int main ()
{
	FILE * Device = NULL;
	int counter = 0;
	
	Device = fopen("/dev/ttyACM0", "w+");
	if(Device == NULL)
	{
		printf("could not open Device\n");
		return -1;
	}

	while (counter < 10)
	{
		fprintf(Device, "%d\n", counter);
		printf("Sent to Device: %d\n", counter);
		counter++;
		sleep(2);
	}

	fclose(Device);

return 0;
}

Код Ардуино:

int cnt = 0;
int strobe = 0;
int num;
int ValidInput = 0;

char intBuffer[12];
String intData = "";
int delimiter = (int) '\n';

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(3, OUTPUT);
}

int input;

void loop()
{
  while(num = Serial.available())
  {
    delay(5);
//  Serial.println(num);
    int ch = Serial.read();
    if(ch == delimiter)
    {
     ValidInput = 1;
     break;
    }
     else
    {
      intData += (char) ch;
    }
  }
  int intLen = intData.length() + 1;
  intData.toCharArray(intBuffer, intLen);
  intData = "";
  int i = atoi(intBuffer);
  
  if(ValidInput)
  {
      if(i == 0)
      {
       strobe = 0;
       Serial.print("Initializing strobe");
      }
      else
      {
       strobe = !strobe;
      }
      
      digitalWrite(3, (strobe) ? HIGH : LOW);
      Serial.println(i);
      ValidInput = 0;
  }
}

Проблемы, которые у меня есть:

  1. Не уверен, является ли fopen правильным способом связи с последовательным устройством в Linux, и если да, то в каком режиме?
  2. Это основная проблема — я испытываю недетерминированное поведение: если я запускаю этот код прямо перед открытием «Последовательного монитора» редактора Arduino, он не работает, как я объяснил выше, вместо этого он включит светодиод, а затем выключится сразу, на каждый входящий новый номер. но как только я открою «Последовательный монитор», он будет действовать так, как я хочу, - меняя состояние светодиода для каждого нового входящего номера.

Я думаю, что это как-то связано со сбросом Arduino или чем-то в этом роде.

Я просмотрел много тем здесь и на других форумах и не нашел решения этой проблемы.

Я был бы очень признателен за ваше понимание.


person Spitz    schedule 17.05.2015    source источник
comment
Ваш код Arduino выглядит разумным. Попробуйте использовать libusb.org для ПК.   -  person Sound Conception    schedule 18.05.2015
comment
@SoundConception - нет, libusb здесь не логичный выбор. USB-устройство управляется серийным USB-модулем/ядром или (в данном случае) драйвером CDC/ACM. Прикладные программы должны использовать Serial API, что и пытается сделать программа. Самая очевидная отсутствующая вещь (и точно коррелирующая с наблюдаемой проблемой) — это конфигурация порта, для которой обычно требуется файловый дескриптор из open(), а не поток из fopen().   -  person Chris Stratton    schedule 18.05.2015


Ответы (2)


Во-первых, сторона Arduino выглядит нормально. Что касается Linux, вам нужно провести некоторые исследования, поскольку последовательная связь в posix-системах немного сложнее, чем просто открытие файла и запись в него. Пожалуйста, используйте справочные страницы linux для termios, где вы можете найти информацию о том, как настроить параметры порта связи, и используйте этот документ http://tldp.org/HOWTO/Serial-Programming-HOWTO/, чтобы на самом деле узнать, как поставить все вместе. Руководство по серийному программированию проведет вас через процесс настройки порта, научиться управлять им и научиться принимать входные данные из нескольких источников. Также для успешного доступа к последовательному порту из непривилегированной учетной записи вам может потребоваться добавить этого пользователя (вашего пользователя) в определенную группу (группу дозвона в Ubuntu и Fedora). Вы можете поискать в Google информацию о доступе к последовательному порту в Linux, и вы можете найти множество примеров кода, готовых для интеграции в ваше приложение. Вы можете найти отличную ссылку и полную документированную реализацию внизу этой темы, а также на SO Как читать данные из последовательного порта в Linux с помощью C?

person JD_GRINDER    schedule 18.05.2015

Простой fopen не устанавливает никаких параметров связи последовательных портов. Вам необходимо установить скорость передачи данных, количество битов, четность и количество стоповых битов. И, если вы хотите использовать линейную дисциплину Linux или нет. Для этого используется структура termio.

Есть пара хороших туториалов о том, как использовать последовательный порт между linux и arduinos.

http://chrisheydrick.com/2012/06/12/how-to-read-serial-data-from-an-arduino-in-linux-with-c-part-1/

http://todbot.com/blog/2006/12/06/arduino-serial-c-code-to-talk-to-arduino/

person johnnynb    schedule 18.05.2015