Записать байт в Arduino из Ruby поверх серийного - PullRequest
7 голосов
/ 06 ноября 2010

Я пытаюсь отправить целое число через последовательный порт на мой Ardunio. Затем микросхема будет отображать число в двоичном виде на светодиодах. Однако у меня много проблем с попыткой отправить данные в виде байта через последовательный порт, так как я могу отлаживать следующий код отправляет их в виде значений ASC-символов.

Кто-нибудь может указать мне правильное направление или определить ошибку? Я действительно ценю это. Я тяну свои волосы над этим в течение долгого времени.

рубин

require 'rubygems'  
require 'serialport' # use Kernel::require on windows, works better.  

#params for serial port  
port_str = "/dev/tty.usbserial-A700dZt3"  #may be different for you  
baud_rate = 9600  
data_bits = 8  
stop_bits = 1  
parity = SerialPort::NONE  

sp = SerialPort.new(port_str, baud_rate, data_bits, stop_bits, parity)  

i = 15

#just write forever  
while true do  
  sp.write(i.to_s(2))
  sleep 10
end

Arduino

int ledPin = 10;
int ledPin1 = 11;
int ledPin2 = 12;
int ledPin3 = 13;

byte incomingByte;  // for incoming serial data

void setup() {
  pinMode(ledPin, OUTPUT);  // initialize the LED pin as an output:
  pinMode(ledPin1, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin2, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin3, OUTPUT); // initialize the LED pin as an output:
  Serial.begin(9600);   
  Serial.println("I am online"); 
}

void loop() {
 // send data only when you receive data:
if (Serial.available() > 0) {
    incomingByte = Serial.read();
            Serial.println(incomingByte, DEC);

   int value = (incomingByte, DEC) % 16;
   digitalWrite(ledPin, (value >> 0) % 2);
   digitalWrite(ledPin1, (value >> 1) % 2);
   digitalWrite(ledPin2, (value >> 2) % 2);
   digitalWrite(ledPin3, (value >> 3) % 2); // MSB

}

}

Ответы [ 4 ]

5 голосов
/ 16 ноября 2010

Полагаю, вы пытаетесь записать значение 15, чтобы зажечь все светодиоды одновременно.Тем не менее, 15.to_s(2) это "1111".Значение ASCII символа '1' равно 49, поэтому вместо записи 15, как только вы пишете 49 четыре раза в быстрой последовательности.

Следовательно, команда записи, которую вы ищете, вероятно, sp.putc(i).При этом записывается только один символ с заданным двоичным значением (= машиночитаемым для Arduino) вместо строкового представления ASCII значения, выраженного в двоичном (= читабельного для вас).

Таким образом, оставив все то же самое, замените цикл while в своем коде Ruby на:

loop do
  sp.putc(i)
  puts 'Wrote: %d = %bb' % [ i, i ]
  i = (i == 15) ? 0 : (i + 1)
  sleep(10)
end

Если вы хотите прочитать ответы от Arduino, вы можете использовать, например, sp.gets, чтобы получить одну строкутекста, например, попробуйте поместить puts 'Arduino replied: ' + sp.gets в цикл перед sleep (и один puts sp.gets перед циклом, чтобы прочитать сообщение "Я онлайн", отправленное при первом установлении соединения).

Edit: Я только что заметил еще одну проблему в вашем коде на стороне Arduino: value = (incomingByte, DEC) % 16; всегда приводит к значению 10, потому что (incomingByte, DEC) имеет значение DEC (что равно 10).Вы должны использовать value = incomingByte % 16; вместо этого.Или полностью исключите value и измените incomingByte, например incomingByte %= 16;.

1 голос
/ 06 ноября 2010

Прошло так много времени с тех пор, как я что-то делал с последовательными портами, и я ничего не могу поделать, но я вижу одну вещь.если вы хотите, чтобы двоичное значение было отправлено, вам потребуется "\xf" или "\u000F".


Измените код с:

while true do  
  sp.write(i.to_s(2)) # <-- this sends a multi-character ASCII representation of the "i" value, NOT the binary.
  sleep 10
end

на:

while true do  
  sp.write(i.chr) # <-- this sends a single byte binary representation of the "i" value, NOT the ASCII.
  sleep 10
end

Чтобы показать разницу, вот длина выводимых строк:

>> 15.to_s(2).size #=> 4
>> 15.chr.size #=> 1

И десятичные значения байтов, составляющих строки:

>> 15.to_s(2).bytes.to_a #=> [49, 49, 49, 49]
>> 15.chr.bytes.to_a #=> [15]
1 голос
/ 06 ноября 2010

Ваши проблемы могут быть вызваны буферизацией. Чтобы отключить буферизацию, вы можете сделать одно из следующего:

1 голос
/ 06 ноября 2010

У меня был этот код Ruby до

while true do
  printf("%c", sp.getc)
end

вместо использования sp.write(i.to_s). Похоже, вы явно конвертируете его в строку, что может быть причиной ваших проблем.

Я нашел оригинальную запись в блоге, которую использовал: http://www.arduino.cc/playground/Interfacing/Ruby

...