График в реальном времени с com-порта
- Войдите на сайт для отправки комментариев
Всем здравия!
Подскажите программу для построения графика в реальном времени на основе данных с com-порта (Если конечно такие имеются). Т.е. есть датчик (gy-521 акселерометр и гироскоп) вывожу с него данные в сом-порт, хотелось бы это всё анализировать в реальном времени визуально. Полдня потратил на поиски программы, так ни чего и не нашел. Максимум чего добился, так это с программы Serial port logger экспортировать данные в реальном времени в excel и в нем уже строить график, НО! Программа платная (60 бакселей) и excel не справляется и тормозит дико, ну это понятно, он не предназначен анализировать такой поток данных в реальном времени. Может кто имеет уже опыт в этом деле.
Заранее спасибо!
Если нужен примитивный осциллограф, что бы посмотреть что происходит на аналоговых выходах. То я обычно запускаю скетч в processing-е.
Скетч processing.
import processing.serial.*; Serial port; // Create object from Serial class int valA; int valB; int valC; int valD; int valE; int valF; // this should have been some kind of 2-diminsional array, I guess, but it works. int[] valuesA; int[] valuesB; int[] valuesC; int[] valuesD; int[] valuesE; int[] valuesF; PFont fontA; PFont fontB; void setup() { // make sure you have these fonts made for Processing. Use Tools...Create Font. // "fontA" is a 48 pt font of some sort. It's what we use to show the "now" value. fontA = loadFont("data/Arial-BoldItalicMT-48.vlw"); // "fontB" is a 14 pt font of some sort. It's what we use to show the min and max values. fontB = loadFont("data/Arial-BoldItalicMT-18.vlw"); // I wouldn't change the size if I were you. There are some functions that don't use // the actual sizes to figure out where to put things. Sorry about that. size(550, 600); // Open the port that the board is connected to and use the same speed // anything faster than 38.4k seems faster than the ADC on the Arduino can keep up with. // So, if you want it to be smooth, keep it at or below 38400. 28800 doesn't work at all, // I do not know why. If you turn on smooth() you need to drop the rate to 19.2k or lower. // You will probably have to adjust Serial.list()[1] to get your serial port. port = new Serial(this,Serial.list()[0], 9600); // Serial.list()[0] // These are 6 arrays for the 6 analog input channels. // I'm sure it could have just as well been a 2d array, but I'm not that familiar // with Processing yet and this was the easy way out. valuesA = new int[width-150]; valuesB = new int[width-150]; valuesC = new int[width-150]; valuesD = new int[width-150]; valuesE = new int[width-150]; valuesF = new int[width-150]; // the -150 gives us room on the side for our text values. // this turns on anti-aliasing. max bps is about 19.2k. // uncomment out the next line to turn it on. Personally, I think it's better left off. //smooth(); } int getY(int val) { // I added -40 to this line to keep the lines from overlapping, to // keep the values within their gray boxes. return (int)(val / 1023.0f * (height-40)) - 1; } void draw() { String decoder = ""; while (port.available() >= 3) { // read serial until we get to an "A". decoder = port.readStringUntil(65); } // sanity check. make sure the string we got from the Arduino has all the values inside. if ((decoder.indexOf("B")>=1) & (decoder.indexOf("C")>=1) & (decoder.indexOf("D")>=1) & (decoder.indexOf("E")>=1) & (decoder.indexOf("F")>=1)) { // decoder string doesn't contain an A at the beginning. it's at the end. valA=int(decoder.substring(0,decoder.indexOf("B"))); //println("A" + str(valA)); valB=int(decoder.substring(decoder.indexOf("B")+1,decoder.indexOf("C"))); //println("B" + str(valB)); valC=int(decoder.substring(decoder.indexOf("C")+1,decoder.indexOf("D"))); //println("C" + str(valC)); valD=int(decoder.substring(decoder.indexOf("D")+1,decoder.indexOf("E"))); //println("D" + str(valD)); valE=int(decoder.substring(decoder.indexOf("E")+1,decoder.indexOf("F"))); //println("E" + str(valE)); valF=int(decoder.substring(decoder.indexOf("F")+1,decoder.indexOf("A"))); //println("F" + str(valF)); } //shift the new values into the array, move everything else over by one for (int i=0; i<width-151; i++) { valuesA[i] = valuesA[i+1]; valuesB[i] = valuesB[i+1]; valuesC[i] = valuesC[i+1]; valuesD[i] = valuesD[i+1]; valuesE[i] = valuesE[i+1]; valuesF[i] = valuesF[i+1]; } // -151 because the array is 151 less than the width. remember we // saved room on the side of the screen for the actual text values. valuesA[width-151] = valA; valuesB[width-151] = valB; valuesC[width-151] = valC; valuesD[width-151] = valD; valuesE[width-151] = valE; valuesF[width-151] = valF; background(0); textFont(fontA); // I'm sure these c/should have been determined using height math, but I don't have the time really. // Draw out the now values with the big font. text(valA + 1, (width-140), 108-5); text(valB + 1, (width-140), 206-5); text(valC + 1, (width-140), 304-5); text(valD + 1, (width-140), 402-5); text(valE + 1, (width-140), 500-5); text(valF + 1, (width-140), 598-5); textFont(fontB); // Draw out the min and max values with the small font. // the h value (30,128,266,etc) is a function of height, // but I didn't bother to actually do the math. // I guess it's (98*n)+30 where n is 0,1,2,3,4,5, but I don't know // exactly how height (600) relates to 98... ((h/6)-2??) drawdata("0", width-90, 30, valuesA); drawdata("1", width-90, 128, valuesB); drawdata("2", width-90, 226, valuesC); drawdata("3", width-90, 324, valuesD); drawdata("4", width-90, 422, valuesE); drawdata("5", width-90, 520, valuesF); for (int x=150; x<width-1; x++) { // next line adjusts the color of the stroke depending on the x value. (fades out the end of the line) check(x,255,0,0); // next line draws the line needed to get this value in the array to the next value in the array. // the offsets (6+ in the next line) were used to get the values where I wanted them without // having to actually do real spacial math. There's a hack in getY that offsets a little, too. line((width)-x, 6+((height/6)*0)+((height-1-getY(valuesA[x-150]))/6), (width)-1-x, 6+((height/6)*0)+((height-1-getY(valuesA[x-149]))/6)); check(x,0,255,0); line((width)-x, 4+((height/6)*1)+((height-1-getY(valuesB[x-150]))/6), (width)-1-x, 4+((height/6)*1)+((height-1-getY(valuesB[x-149]))/6)); check(x,0,0,255); line((width)-x, 2+((height/6)*2)+((height-1-getY(valuesC[x-150]))/6), (width)-1-x, 2+((height/6)*2)+((height-1-getY(valuesC[x-149]))/6)); check(x,255,255,0); line((width)-x, 0+((height/6)*3)+((height-1-getY(valuesD[x-150]))/6), (width)-1-x, 0+((height/6)*3)+((height-1-getY(valuesD[x-149]))/6)); check(x,0,255,255); line((width)-x, -2+((height/6)*4)+((height-1-getY(valuesE[x-150]))/6), (width)-1-x, -2+((height/6)*4)+((height-1-getY(valuesE[x-149]))/6)); check(x,255,0,255); line((width)-x, -4+((height/6)*5)+((height-1-getY(valuesF[x-150]))/6), (width)-1-x, -4+((height/6)*5)+((height-1-getY(valuesF[x-149]))/6)); } // draw the boxes in gray. stroke(170,170,170); // these 5 lines divide the 6 inputs line(0,108,width-1,108); line(0,206,width-1,206); line(0,304,width-1,304); line(0,402,width-1,402); line(0,500,width-1,500); // these four lines make up the outer box line( 0, 0, width-1, 0); // along the top line(width-1, 0, width-1, height-1); // down the right line(width-1, height-1, 0, height-1); // along the bottom line( 0, height-1, 0, 0); // up the left } void drawdata(String pin, int w, int h, int[] values) { text("pin: " + pin, w, h); text("min: " + str(min(values) + 1), w, h + 14); text("max: " + str(max(values) + 1), w, h + 28); } void check(int xx, int rr, int gg, int bb) { // floating point operations in Processing are expensive. // only do the math for the float (fading out effect) if // we have to. You can change 170 to 160 if you want it to // fade faster, but be sure to change the other 170 to 160 // and the 20 to 10. // (20 is the difference between 170 and 150) if (xx<=170) { float kick = (parseFloat(170-xx)/20)*255; // invert kick so the brighter parts are on the left side instead of the right. stroke(rr,gg,bb,255-kick); } else { stroke(rr,gg,bb); } }Скетч arduino.
#define ANALOGA_IN 0 #define ANALOGB_IN 1 #define ANALOGC_IN 2 #define ANALOGD_IN 3 #define ANALOGE_IN 4 #define ANALOGF_IN 5 int counter = 0; void setup() { Serial.begin(9600); } void loop() { int val[5]; val[0] = analogRead(ANALOGA_IN); val[1] = analogRead(ANALOGB_IN); val[2] = analogRead(ANALOGC_IN); val[3] = analogRead(ANALOGD_IN); val[4] = analogRead(ANALOGE_IN); val[5] = analogRead(ANALOGF_IN); Serial.print( "A" ); Serial.print( val[0] ); Serial.print( "B" ); Serial.print( val[1] ); Serial.print( "C" ); Serial.print( val[2] ); Serial.print( "D" ); Serial.print( val[3] ); Serial.print( "E" ); Serial.print( val[4] ); Serial.print( "F" ); Serial.print( val[5] ); }Думаю, это то что нужно! Сегодня поковыряюсь. Спасибо! :)
https://www.google.ru/?gws_rd=ssl#newwindow=1&q=arduino+serial+plotter+m...
https://www.youtube.com/watch?v=Z1QWFoYa1pU
https://www.norwegiancreations.com/2016/01/tutorial-multiple-values-in-the-arduino-ide-serial-plotter/
https://www.google.ru/?gws_rd=ssl#newwindow=1&q=arduino+serial+plotter+m...
https://www.youtube.com/watch?v=Z1QWFoYa1pU
https://www.norwegiancreations.com/2016/01/tutorial-multiple-values-in-the-arduino-ide-serial-plotter/
У меня с плоттером ни чего не получилось, я вкуривть не стал что это такое, а оказывается, вон оно чё Михалыч :) Ну если честно, то с processing'ом мне больше понравилось, потравил времени конечно на него, но зато результат радует глаз :), осталось только подкалибровать его.
http://www.megunolink.com/
Когда-то использовал это
Я использую программу RealVeiw3.