- Beranda
- Programmer Forum
[ASK] Sinkronisasi tampilan GUI Visual Studio C# dengan input data Arduino
...
TS
autis++idiott
[ASK] Sinkronisasi tampilan GUI Visual Studio C# dengan input data Arduino
Hai gan
Jadi gini gan: ane lagi buat GUI untuk monitorin konsentrasi air garam berbasis arduino. Prinsipnya menggunakan analogread. Ane udah sampai pada tahap monitoring perubahan konsentrasi dalam bentuk grafik pakai zedgraph, cuma masih terkendala masalah sinkronisasi delay antara arduino dengan visual studio. jadi grafik yang ane dapet pergerakannya tidak sesuai dengan data yang saya dapatkan dari serial monitor arduino. Ini untuk lebih jelasnya gan:
Jadi sistemnya baru dinyalain selama kurang dr 10 detik, tapi grafiknya udah ngacir same 100 detik. kalau di serial monitor arduino sih bagus-bagus aja.. datanya keupdate tiap 1 detik.
Btw ini code arduino ane gan:
Dan ini visual studionya gan:
Beberapa orang yg udah ane tanya pada bilang kalau itu solusinya pakai threading di interfacenya Ane masih ga begitu paham cara nambahin threadingnya. Minta bantuannya ya gan
Terima kasih sebelumnya
Jadi gini gan: ane lagi buat GUI untuk monitorin konsentrasi air garam berbasis arduino. Prinsipnya menggunakan analogread. Ane udah sampai pada tahap monitoring perubahan konsentrasi dalam bentuk grafik pakai zedgraph, cuma masih terkendala masalah sinkronisasi delay antara arduino dengan visual studio. jadi grafik yang ane dapet pergerakannya tidak sesuai dengan data yang saya dapatkan dari serial monitor arduino. Ini untuk lebih jelasnya gan:
Jadi sistemnya baru dinyalain selama kurang dr 10 detik, tapi grafiknya udah ngacir same 100 detik. kalau di serial monitor arduino sih bagus-bagus aja.. datanya keupdate tiap 1 detik.
Btw ini code arduino ane gan:
Spoiler for arduino:
Code:
// #
// # Editor : YouYou from DFRobot
// # Date : 23.04.2014
// # E-Mail : [email]youyou.yu@dfrobot.com[/email]
// # Product name: Analog EC Meter
// # Product SKU : DFR0300
// # Version : 1.0
// # Description:
// # Sample code for testing the EC meter and get the data feedback from the Arduino Serial Monitor.
// # Connection:
// # EC meter output -> Analog pin 1
// # DS18B20 digital pin -> Digital pin 2
// #
#include <OneWire.h>
#define StartConvert 0
#define ReadTemperature 1
const byte numReadings = 20; //the number of sample times
byte ECsensorPin = A1; //EC Meter analog output,pin on analog 1
byte DS18B20_Pin = 2; //DS18B20 signal, pin on digital 2
unsigned int AnalogSampleInterval=25,printInterval=700,tempSampleInterval=850; //analog sample interval;serial print interval;temperature sample interval
unsigned int readings[numReadings]; // the readings from the analog input
byte index = 0; // the index of the current reading
unsigned long AnalogValueTotal = 0; // the running total
unsigned int AnalogAverage = 0,averageVoltage=0; // the average
unsigned long AnalogSampleTime,printTime,tempSampleTime;
float temperature,ECcurrent;
//Temperature chip i/o
OneWire ds(DS18B20_Pin); // on digital pin 2
void setup() {
// initialize serial communication with computer:
Serial.begin(9600);
// initialize all the readings to 0:
for (byte thisReading = 0; thisReading < numReadings; thisReading++)
readings[thisReading] = 0;
TempProcess(StartConvert); //let the DS18B20 start the convert
AnalogSampleTime=millis();
printTime=millis();
tempSampleTime=millis();
}
void loop() {
/*
Every once in a while,sample the analog value and calculate the average.
*/
if(millis()-AnalogSampleTime>=AnalogSampleInterval)
{
AnalogSampleTime=millis();
// subtract the last reading:
AnalogValueTotal = AnalogValueTotal - readings[index];
// read from the sensor:
readings[index] = analogRead(ECsensorPin);
// add the reading to the total:
AnalogValueTotal = AnalogValueTotal + readings[index];
// advance to the next position in the array:
index = index + 1;
// if we're at the end of the array...
if (index >= numReadings)
// ...wrap around to the beginning:
index = 0;
// calculate the average:
AnalogAverage = AnalogValueTotal / numReadings;
}
/*
Every once in a while,MCU read the temperature from the DS18B20 and then let the DS18B20 start the convert.
Attention:The interval between start the convert and read the temperature should be greater than 750 millisecond,or the temperature is not accurate!
*/
if(millis()-tempSampleTime>=tempSampleInterval)
{
tempSampleTime=millis();
temperature = TempProcess(ReadTemperature); // read the current temperature from the DS18B20
TempProcess(StartConvert); //after the reading,start the convert for next reading
}
/*
Every once in a while,print the information on the serial monitor.
*/
if(millis()-printTime>=printInterval)
{
printTime=millis();
averageVoltage=AnalogAverage*(float)5000/1024;
///Serial.print("Analog value:");
//Serial.print(AnalogAverage); //analog average,from 0 to 1023
//Serial.print(" Voltage:");
//Serial.print(averageVoltage); //millivolt average,from 0mv to 4995mV
//Serial.print("mV ");
//Serial.print("temp:");
//Serial.print(temperature); //current temperature
//Serial.print("^C EC:");
float TempCoefficient=1.0+0.0185*(temperature-25.0); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.0185*(fTP-25.0));
float CoefficientVolatge=(float)averageVoltage/TempCoefficient;
if(CoefficientVolatge<150)Serial.println("No solution!"); //25^C 1413us/cm<-->about 216mv if the voltage(compensate)<150,that is <1ms/cm,out of the range
else if(CoefficientVolatge>3300)Serial.println("Out of the range!"); //>20ms/cm,out of the range
else
{
if(CoefficientVolatge<=448)ECcurrent=6.84*CoefficientVolatge-64.32; //1ms/cm<EC<=3ms/cm
else if(CoefficientVolatge<=1457)ECcurrent=6.98*CoefficientVolatge-127; //3ms/cm<EC<=10ms/cm
else ECcurrent=5.3*CoefficientVolatge+2278; //10ms/cm<EC<20ms/cm
ECcurrent/=1000; //convert us/cm to ms/cm
Serial.println(ECcurrent,2); //two decimal
//Serial.println("ms/cm");
}
}
}
/*
ch=0,let the DS18B20 start the convert;ch=1,MCU read the current temperature from the DS18B20.
*/
float TempProcess(bool ch)
{
//returns the temperature from one DS18B20 in DEG Celsius
static byte data[12];
static byte addr[8];
static float TemperatureSum;
if(!ch){
if ( !ds.search(addr)) {
Serial.println("no more sensors on chain, reset search!");
ds.reset_search();
return 0;
}
if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return 0;
}
if ( addr[0] != 0x10 && addr[0] != 0x28) {
Serial.print("Device is not recognized!");
return 0;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
}
else{
byte present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for (int i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
ds.reset_search();
byte MSB = data[1];
byte LSB = data[0];
float tempRead = ((MSB << 8) | LSB); //using two's compliment
TemperatureSum = tempRead / 16;
}
return TemperatureSum;
}
Dan ini visual studionya gan:
Spoiler for visual studio:
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
//namespace untuk zedGrpah
using ZedGraph;
//namespace untuk class serial
using System.IO.Ports;
//namespace untuk melihat setting global komputer
using System.Globalization;
namespace Monitor_Suhu
{
public partial class Form_utama : Form
{
/**Inisialisaisi arduino
* Setup port serial dengan nama port COM65,
* dan baud rate sebesar 9600.
* Baud rate disini dengan di arduino harus sama
* **/
SerialPort arduino = new SerialPort("COM6", 9600);
//waktu mulai dalam milidetik
double waktuStart = 100;
//konstruktor
public Form_utama()
{
InitializeComponent();
}
//event ketuka tombol start diklik
private void btn_kontrol_start_Click(object sender, EventArgs e)
{
//start detak untuk mulai mengaktifkan grapher
try
{
//matikan tombol start
btn_kontrol_start.Enabled = false;
//nyalakan tombol stop
btn_kontrol_stop.Enabled = true;
//set batas waktu pembacaan serial sebelum dinyatakan gagal
arduino.ReadTimeout = 1000;
//set batas waktu penulisan serial
arduino.WriteTimeout = 1000;
//nyalakan detak
Detak.Enabled = true;
//mulai detak
Detak.Start();
}
catch (Exception gagal)
{
//Error handling
//MessageBox.Show(gagal.ToString());
}
}
//event ketika detak dimulai
private void Detak_Tick(object sender, EventArgs e)
{
try
{
//Mulai komunikasi dengan arduino
arduino.Open();
//get item kurva pertama pada grafik
LineItem kurvaSuhu = zedGraphSuhu.GraphPane.CurveList[0] as LineItem;
//get PointPairList
IPointListEdit listSuhu = kurvaSuhu.Points as IPointListEdit;
//waktu yang terlewati
double waktu = (Environment.TickCount - waktuStart) / 1000.0;
//baca data suhu yang dikirim arduino,
//konversi data tersebut (string) ke double,
//dan tambahkan ke listSuhu
float dataSuhu = float.Parse(arduino.ReadLine(), CultureInfo.InvariantCulture.NumberFormat);
listSuhu.Add(waktu,Convert.ToDouble(dataSuhu));
//Tutup komunikasi dengan arduino
arduino.Close();
//Buat scale X tetap rolling dalam interval 30 detik, dengan satu
//langkah besar antara nilai X maksimal dan akhir dari axis
Scale xScale = zedGraphSuhu.GraphPane.XAxis.Scale;
if (waktu > xScale.Max - xScale.MajorStep)
{
xScale.Max = waktu + xScale.MajorStep;
xScale.Min = xScale.Max - 30.0;
}
// Pastikan Y axis di scale ulang untuk mengakomodir data aktual
zedGraphSuhu.AxisChange();
// Redraw paksa
zedGraphSuhu.Invalidate();
}
catch (Exception gagal)
{
//error handling
//tutup komunikasi dengan arduino jika masih terhubung
if (arduino.IsOpen)
{
arduino.Close();
}
//MessageBox.Show(gagal.ToString());
}
}
//event ketika tombol stop diklik
private void btn_kontrol_stop_Click(object sender, EventArgs e)
{
try
{
//nyalakan kembali tombol start
btn_kontrol_start.Enabled = true;
//matikan tombol stop
btn_kontrol_stop.Enabled = false;
//stop detak
Detak.Stop();
//matikan detak
Detak.Enabled = false;
//jika komunikasi masih terbuka, tutup komunikasi
if (arduino.IsOpen)
{
arduino.Close();
}
}
catch (Exception gagal)
{
//error handling
//MessageBox.Show(gagal.ToString());
}
}
//event ketika form utama dibuka
private void Form_utama_Load(object sender, EventArgs e)
{
try
{
//catat waktu pertama sebagai referensi
waktuStart = Environment.TickCount;
//Inisialisasi ZedGraph
GraphPane grafikSuhu = zedGraphSuhu.GraphPane;
grafikSuhu.Title.Text = "Concentration Graph";
grafikSuhu.XAxis.Title.Text = "Time (Second)";
grafikSuhu.YAxis.Title.Text = "Concentration (mol/litre)";
//Simpan 120 point. Pada 500 ms sampel rate.
//RollingPointPairList adalah class penyimpanan yang efisien
//dengan tetap merolling kumpulan point data tanpa perlu
//men-shift nilai data apapun
RollingPointPairList listSuhu = new RollingPointPairList(60000);
//Inisialisasi kurva
LineItem kurvaSuhu = grafikSuhu.AddCurve("Concentration", listSuhu, Color.Red,SymbolType.None);
}
catch (Exception gagal)
{
//error handling
//MessageBox.Show(gagal.ToString());
}
}
}
}
Beberapa orang yg udah ane tanya pada bilang kalau itu solusinya pakai threading di interfacenya Ane masih ga begitu paham cara nambahin threadingnya. Minta bantuannya ya gan
Terima kasih sebelumnya
0
3.7K
Kutip
6
Balasan
Komentar yang asik ya
Mari bergabung, dapatkan informasi dan teman baru!
Programmer Forum
20.2KThread•4.7KAnggota
Urutkan
Terlama
Komentar yang asik ya