Комуникация между C & Arduino

От известно време се боря с този проблем и той ме побърква:

Опитвам се да комуникирам много просто с Arduino Mega 2560 (чрез USB като серийно устройство) от компютър, работещ с Linux (Knoppix на usb-dok), когато всичко, което се опитвам да постигна на този етап, е, че за всеки номер, изпратен от лаптоп към Arduino, сигналът „stobe“ ще превключи от High на Low или обратното и аз използвам този светлинен светлинен сигнал, за да включа и изключа светодиод.

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;
}

Код на Arduino:

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 драйвер. Приложните програми трябва да използват серийния API, което се опитва да направи програмата. Най-очевидното липсващо нещо (и точно свързано с наблюдавания проблем) е конфигурацията на порта и това обикновено изисква файлов дескриптор от open(), а не поток от fopen().   -  person Chris Stratton    schedule 18.05.2015


Отговори (2)


Първо, страната на arduino изглежда добре. От страна на Linux трябва да направите малко проучване, тъй като серийната комуникация на posix системите е малко по-сложна от отварянето на файл и записването в него. Моля, използвайте man страниците на 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 line или не. За това се използва структурата 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