Проблема со связью arduino/mac с использованием ORSSerialPort

Я пытаюсь отправить трехзначное число из инструмента командной строки XCode Foundation на Arduino через USB в качестве доказательства концепции отправки потока данных. Предполагается, что код Arduino должен мигать светом столько раз, сколько указано во входящих данных. Он отлично работает с последовательным монитором в IDE arduino, но когда я пытаюсь использовать программу Objective-C, которая использует ORSSerialPort, на arduino мигает индикатор Rx, указывая на то, что он получил данные, но больше ничего не происходит.

Вот код цели-C:

#import <Foundation/Foundation.h>
#import <IOKit/IOKitLib.h>
#import "ORSSerialPort.h"
#import "ORSSerialPortManager.h"



int main(int argc, const char * argv[])
{
    @autoreleasepool {

        ORSSerialPort *arduino = [ORSSerialPort serialPortWithPath:@"/dev/tty.usbmodem26231"];
        //initalizes ORSSerialPort instance

        NSString *string = @"012"; //creates string from the 3-digit number

        NSData *outgoingdata = [string dataUsingEncoding:NSASCIIStringEncoding]; 
        //encodes string using ASCII

        int number = 1200;
        NSNumber *baudrate = [[NSNumber alloc] initWithInt:number];
        //initializes an NSNumber for the baud rate

        [arduino open]; //opens port
        baudrate = arduino.baudRate; //sets baud rate
        [arduino sendData:outgoingdata]; //sends data
        [arduino close]; //closes port

        NSLog(@"%@ sent", string); //logs the number
    }   
    return 0;
}

Вот код ардуино:

#include <SoftwareSerial.h>

int i100;
int i10;
int i1;
int total;

void setup() {
  Serial.begin(1200);
  pinMode(2, OUTPUT);
}

void loop() {
int mail = Serial.available(); //reads number of available bytes
  if(mail >= 3) {
    int i100raw = Serial.read()-48; //reads 3 bytes and decodes from ASCII by subtracting 48
    int i10raw = Serial.read()-48;  
    int i1raw = Serial.read()-48; 

    if(i1raw >= 0) {  //checks if each byte is a valid input 
      i100 = i100raw; 
    }
    if(i10raw >= 0) {
      i10 = i10raw; 
    }
    if(i1raw >= 0) {
      i1 = i1raw; 
    }

    total = (i100*100)+(i10*10)+(i1); //puts together 3 digit number from 3 bytes

    while(total > 0) {       //flashes light  
      digitalWrite(2, HIGH);
      delay(50);
      digitalWrite(2, LOW);
      delay(50);
      total--;
    }   
  }
} 

person JP762    schedule 14.03.2014    source источник


Ответы (2)


Пара мыслей:

  1. Основная проблема в том, что вы никогда не устанавливаете baudRate для ORSSerialPort. (У вас есть это назначение в обратном порядке.) Кроме того, в примерах, которые я видел, скорость передачи в бодах устанавливается в ORSSerialPort перед открытием порта. Итак, я бы предложил:

    arduino.baudRate = @(1200); //sets baud rate
    [arduino open];             //opens port
    
  2. Кроме того, в моем тесте, если бы я попытался закрыть порт Arduino сразу после записи данных, они не были бы получены. Возможно, вы захотите немного подождать, прежде чем закрыть этот порт.

  3. Вы также можете использовать новый терминатор строки для того, что вы отправляете в Arduino. Это, очевидно, изменение как в коде отправки, так и в коде получения, но оно будет немного более надежным, чем просто чтение следующих трех байтов.

  4. Я также могу предположить, что если вы хотите быть особенно осторожным, вы можете установить delegate для объекта ORSSerialPort и реализовать методы ORSSerialPortDelegate. Там есть метод сообщения об ошибках, которым вы можете воспользоваться.

  5. Когда я begin подключаю Serial к Arduino, я включаю цикл, ожидающий подключения Serial. Фрагмент кода, из которого я взял это, говорит, что это необходимо только для Leonardo, но стоит попробовать, если вы обнаружите, что не можете успешно получать данные при первом открытии соединения со стороны Mac:

    void setup() 
    {
      pinMode(2, OUTPUT);
    
      Serial.begin(1200); 
      while (!Serial) {
        // wait for serial port to connect. Needed for Leonardo only
      } 
    
      Serial.println("OK. Connected.");
    }
    

    Кроме того, когда ваш loop() успешно считывает ввод с Serial, вы можете заставить Arduino записать материал обратно (через Serial.println), который вы можете прочитать на своем Mac, чтобы подтвердить успешное получение данных. По сути, это способ подтверждения получения команды, который поможет вам отделить проблемы, связанные со связью, от проблем с проводкой.

person Rob    schedule 14.03.2014
comment
Правильная установка скорости передачи и добавление задержки перед закрытием порта не решили проблему, в настоящее время работают над тем, как интегрировать новый терминатор линии. - person JP762; 14.03.2014
comment
Я ошибся в последнем комментарии. Я только что понял, что после открытия порта должна быть задержка, как и перед его закрытием. - person JP762; 14.03.2014
comment
Кроме того, кажется, что задержка должна быть не менее 2 секунд. - person JP762; 14.03.2014
comment
хех - только что написал ответ, чтобы предложить вам добавить отсрочку. Да, это должно быть несколько секунд. Есть способ отключить сброс Arduino, если это то, что вам нужно, или просто добавить задержку в свой код Obj-C. - person spring; 14.03.2014
comment
FWIW, с моим Uno задержка после открытия не требуется. Только перед закрытием. Но на Леонардо вам придется подождать после звонка Serial.begin(). - person Rob; 14.03.2014
comment
Очень небольшое замечание по первому пункту в этом ответе: ORSSerialPort с радостью позволит вам установить/изменить скорость передачи данных после открытия порта. Конечно, не помешает (и, как правило, имеет больше смысла) установить его перед открытием порта. - person Andrew Madsen; 12.05.2015
comment
@AndrewMadsen - Согласен. Я не пытался придавать этому большое значение. Моя точка зрения на то, что он имел это задом наперёд, заключалась в том, что у него было baudrate = arduino.baudRate вместо arduino.baudRate = baudrate. Повторная установка скорости передачи перед открытием должна была просто предложить передовую практику, но ключевым моментом является то, что на самом деле он не устанавливал скорость передачи, а просто читал ее. И это явно не входило в его планы. - person Rob; 12.05.2015
comment
@Rob, извините, я не имел в виду, что суть этого пункта была неправильной. Назначение скорости передачи в обратном направлении действительно было реальной проблемой. Я просто не хотел, чтобы люди столкнулись с этим вопросом / ответом и подумали, что существует ограничение на установку скорости передачи после открытия. Спасибо и за хороший ответ (я проголосовал за него, когда вы изначально опубликовали). - person Andrew Madsen; 12.05.2015

Только что встретил ту же проблему и решил. Установка DTR на 1, вероятно, решит эту проблему.

arduino.DTR = YES;
person Upfly    schedule 18.12.2020