Arduino и обработка вызова и ответа не работает
Я пытался разработать соединение от arduino IDE к обработке, чтобы я мог отправлять данные, измеренные на выводах arduino, в обработку для отображения.
Сначала я упаковал 10-битные целые числа, которые я получал от arduino, в символы, каждый со своим собственным байтом. Например, 1023 было 10-битным целым числом, которое я упаковал в 4 8-битных символа: 1, 0, 2 и 3. Затем они могли быть отправлены через последовательный порт и восстановлены на другом конце путем обработки.
Тем не менее, я пытался установить связь вызова и ответа между ними, когда после того, как одна программа закончила прием и обработку данных, она просит другую отправить следующий набор.
Я использовал пример кода, приведенный на сайте arduino, который прекрасно работает сам по себе. Но когда я пытаюсь внедрить в него упаковку символов, он перестает работать. Выход в обработке всегда пропускает первую пару символов.
Более того, я удалил myPort.print('A') из кода обработки, и arduino все еще многократно отправлял данные, несмотря на то, что обработка не отправляла ответ обратно.
Это неопределенный вопрос, но где я ошибся при реализации упаковочного кода? и почему arduino продолжает посылать данные независимо от того, отвечает ли обработка?
Большое спасибо
===================================
Код Arduino:
int inByte = 0;
//void establishContact();
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
establishContact();
}
void loop() {
// put your main code here, to run repeatedly:
if (Serial.available() > 0) {
// get incoming byte:
//inByte = Serial.read();
int MzValue = analogRead(A0);
int FzValue = analogRead(A1);
int FyValue = analogRead(A2);
char Mz_Str[10];
char Fz_Str[10];
char Fy_Str[10];
sprintf(Mz_Str, "%d", MzValue);
sprintf(Fz_Str, "%d", FzValue);
sprintf(Fy_Str, "%d", FyValue);
// Now str contains the integer as characters
Serial.write(Mz_Str);
Serial.write(",");
Serial.write(Fz_Str);
Serial.write(",");
Serial.write(Fy_Str);
Serial.write(",");
Serial.write("\n");
delay(20);
}
else {
delay(20);
}
}
void establishContact() {
while (Serial.available() <= 0) {
Serial.print('A'); // send a capital A
delay(1000);
}
}
=================================== Код обработки:
import processing.serial.*;
Serial myPort; // The serial port
boolean firstContact = false; // Whether we've heard from the microcontroller
String val; // Data received from the serial port
int numValues = 3;
float[] values = new float[numValues];
int inByte = 0;
void setup() {
size(256, 256); // Stage size
noStroke(); // No border on the next thing drawn
// Print a list of the serial ports for debugging purposes
// if using Processing 2.1 or later, use Serial.printArray()
println(Serial.list());
// I know that the first port in the serial list on my Mac is always my FTDI
// adaptor, so I open Serial.list()[0].
// On Windows machines, this generally opens COM1.
// Open whatever port is the one you're using.
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
}
void draw() {
// read a byte from the serial port:
if ( myPort.available() > 0) {
inByte = myPort.read();
}
//print(inByte);
// if this is the first byte received, and it's an A, clear the serial
// buffer and note that you've had first contact from the microcontroller.
// Otherwise, add the incoming byte to the array:
if (firstContact == false) {
if (inByte == 'A') {
myPort.clear(); // clear the serial port buffer
firstContact = true; // you've had first contact from the microcontroller
myPort.write('A'); // ask for more
println(inByte);
}
}
else {
val = myPort.readStringUntil('\n'); // read it and store it in val
println(val); //print it out in the console
values = float(splitTokens(val, ","));
myPort.write('A');
delay(20);
}
}
@Tom, 👍1
Обсуждение1 ответ
Почему бы просто не отправить все данные сразу, в списке, разделенном запятыми, с символом \n
в качестве разделителя "конец сообщения"?
Вот 2 тестовых скетча. Скетч Arduino отправляет значения от A0 до A2 в последовательный режим каждые 500 мс, а скетч обработки отображает полученные данные. Анализ полученных данных в целочисленный массив-это скорее вопрос Java, а не Arduino, поэтому я оставлю это на ваше усмотрение.
Ардуино
// Отправляйте значения A0, A1 и A3
// на последовательный каждые 500 мс.
// 2416 байт.
char data[20];
char buffer[6];
void setup(){
Serial.begin(9600);
}
void loop(){
itoa(analogRead(A0), buffer, 10);
strcat(data, buffer);
strcat(data, ",");
itoa(analogRead(A1), buffer, 10);
strcat(data, buffer);
strcat(data, ",");
itoa(analogRead(A2), buffer, 10);
strcat(data, buffer);
strcat(data, "\n");
Serial.write(data);
memset(data, 0, sizeof(data));
delay(500);
}
Обработка
// Отображение данных, полученных из последовательного порта, отправляемых через
// 500 мс от Arduino. Значения, отправленные из A0, A1
// и A2, были отправлены вместе в виде запятых
// разделенный список, за которым следует символ \n.
import processing.serial.*;
import java.awt.TextArea;
Serial myPort;
TextArea myTextArea;
String input;
void setup(){
try{
myPort = new Serial(this, Serial.list()[0], 9600);
}
catch(Exception e){
System.err.println(e);
e.printStackTrace();
}
myTextArea = new TextArea("", 23, 49, 1);
this.add(myTextArea);
size(500, 380);
}
void draw(){
if(myPort.available() > 0){
input = myPort.readStringUntil('\n');
myTextArea.append(input);
}
}
Обновление
Как упоминает Юрай в своих комментариях, я мог бы просто использовать Serial.print()
6 раз вместо массивов символов
. Вот второй скетч Arduino, который использует Serial.print()
. Прежде чем использовать его, имейте в виду, что его размер компиляции на 288 байт больше, чем метод массива символов. Представьте себе это :)
// Отправляйте значения A0, A1 и A3
// на последовательный каждые 500 мс.
// 2704 байта.
void setup(){
Serial.begin(9600);
}
void loop(){
Serial.print(analogRead(A0));
Serial.print(",");
Serial.print(analogRead(A1));
Serial.print(",");
Serial.print(analogRead(A2));
Serial.print("\n");
delay(500);
}
Почему бы не "распечатать" данные в Serial как " Serial.print(analogRead(A0)); Serial.print(',');`...?, @Juraj
@Juraj, это тоже сработало бы :), @VE7JRO
это будет 6 простых строк. никаких буферов, никаких функций языка C. и почему снова мемсет?, @Juraj
вам нужно только buffer[0] = 0
; в начале цикла, чтобы "очистить" строку, @Juraj
Я знаю. Мне нравится использовать memset()
для установки всего массива в 0. Как насчет этого: memset(данные, 0, 1);
Это приводит к тому же размеру компиляции, что и буфер[0] = 0;
и делает то же самое. Конечно, никто не заставляет вас использовать " memset()`., @VE7JRO
- Построение графика на Python с использованием Tkinter Canvas
- Что является более быстрой альтернативой parseInt()?
- SerialUSB на Arduino Due
- Использование экрана SD-карты на Arduino Due
- Связь между Python и Arduino ненадежна
- Serial.availableForWrite против Serial.flush
- Отправка информации (например, строки) через цифровые контакты
- Проблемы с I2C и Wire.Available()
Serial.print(MzValue);
сделает то же самое, что и ваша "упаковка символов", @Jurajвы не читаете доступный символ, поэтому он остается доступным, @Juraj
Processing + Firmata также является потенциальным решением., @Dave Newton