Визуализация данных с Arduino часть 1

May 19, 2017 15:39

Решил начать новый цикл, обнаружилось, что не могу запустить старые скетчи Arduino. Возникают вопросы, как соединить датчики, какие библиотеки использовать и т.д. Поэтому решил расписать все подробно.

Данные с датчиков можно вывести на индикатор, но нужно видеть данные во времени. Arduino и Processing могут обмениваться данными через серийный порт. Пока речь идет только о передача данных, когда Arduino передает данные, а Processing принимает и обрабатывает.
Начал я с простого - Serial.print (“1234”), данные передаются нормально в мониторе порта и в Processing отображается String (“1234”), однако при преобразовании его в цифру выскакивает ошибка преобразования и никакие усилия не помогли.

Для Processing
while (port.available() > 0)
{
String inBuffer = port.readStringUntil('\n');
if (inBuffer != null)
{
trim(inBuffer);
print(inBuffer); //1234
//Sensor = Integer.parseInt(inBuffer); // ошибка
// Sensor = int(inBuffer); // ошибка
println(Sensor);
}
}

Пришлось перейти на Serial.write тут сразу возникла проблема преобразования формата в байт.

Для целых чисел программа для Arduino:

void setup() {
Serial.begin(115200);
}
void loop() {
int reg = analogRead(A0);
byte ch=byte(reg>>8); // старший байт
byte cl=byte(reg & 0xFF); // старший байт
Serial.write(cl);
Serial.write(ch);
// ждем 500 миллисекунд перед следующей отправкой
delay(500);
}

Для Processing

import processing.serial.*;

Serial port; // создаем объект последовательного порта
String received; // данные, получаемые с последовательного порта

void setup()
{
port = new Serial(this, Serial.list()[1],(115200)); // [1] - номер в списке Com портов
}

void draw() {
while (port.available() > 0)
{
int ch = port.read();//получить 1 байт
int cl = port.read();//получить 2 байт
int Sensor = cl*256+ch; // перевести в int
println(Sensor);
}
}

Для дробных чисел, похоже, только для float надо 4 байта, а для double 8 байт. Поиски алгоритма преобразования затянулись, найденные работали в Processing, но не в Arduino. Решил плюнуть на точность, оставить 3 знака после запятой, для датчиков интервала хватает.

Для Arduino:

double ldo;
float flo;

void writeSR (int reg)
{
byte ch=byte(reg>>8);
byte cl=byte(reg & 0xFF);
// ждем 500 миллисекунд перед следующей отправкой
delay(500);
}

void setup()
{
Serial.begin(115200);
ldo=123.456789;
flo = ldo;
}

void loop() {
int ref = ldo; //получение целого
int ret=(flo-ref)*1000; //получение дробного
writeSR (ref);
writeSR (ret);
}

Для Processing

import processing.serial.*;

Serial port; // создаем объект последовательного порта
String received; // данные, получаемые с последовательного порта
int Sensor;
int ch, ch1, cl, cl1, fg, Senso;

void setup()
{
port = new Serial(this, Serial.list()[1],(115200));
}

void draw()
{
while (port.available() > 0)
{
ch = port.read();
cl = port.read();
ch1 = port.read();
cl1 = port.read();
fg = cl*256+ch;
Senso = cl1*256+ch1; //123
float Se=fg; //456
float sens = Senso + Se/1000; //123.456
//print(" sens "); println(sens);
}

}

Все это работает, передает данные, но много ошибок лезет. Попытки как то улучшить ситуацию, ни к чему, не привели, но время написания статьи, нашел способ - нужно передавать маркер начала передачи, но пока есть проблемы. Для визуализации данных использовал библиотеку Grafica.

import processing.serial.*;
import grafica.*;

GPlot plot;
Serial port; // создаем объект последовательного порта
String received; // данные, получаемые с последовательного порта

int i, l = 0; // variable that changes for point calculation
int points = 950; // number of points to display at a time
int totalPoints = 1500; // number of points on x axis
int ch, ch1, cl, cl1,lost ;
float max, min,fg, Senso;

void setup()
{
size (900,450);
port = new Serial(this, Serial.list()[1],(115200));
// initialise graph points object
GPointsArray points1 = new GPointsArray(points);

// Create the plot
plot = new GPlot(this);
plot.setPos(25, 25); // set the position of to left corner of plot
plot.setDim(750, 300); // set plot size

// Set the plot limits (this will fix them)
plot.setXLim(0, totalPoints); // set x limits
plot.setYLim(30, 150); // set y limits
// Add the two set of points to the plot
plot.setPoints(points1);
}

void draw()
{
while (port.available() > 0)
{
ch = port.read();
cl = port.read();
ch1 = port.read();
cl1 = port.read();

fg = cl*256+ch;
Senso = cl1*256+ch1;
float Se=fg;
float val = Se + Senso/1000;

plot.beginDraw();
plot.drawBackground();
plot.drawBox();
plot.drawXAxis();
plot.drawYAxis();
plot.drawTopAxis();
plot.drawRightAxis();
plot.drawTitle();
plot.getMainLayer().drawPoints();
plot.endDraw();
// Add the point at the end of the array
l++;
plot.addPoint(l,val);
}
}

Число ошибок зависит от скорости при115200ошибок 2-3%, то на 2400 уже 50% .

arduino

Previous post Next post
Up