I'm trying to make a fairly simple program that takes temperature data from an Arduino Uno and sends it to VB 2010 to make a real time graph. So far I have the Arduino output temperatures on a new line, I know this works from the Arduino IDE serial monitor.
Basically I can get input but is not what I should be reading. Arduino is putting out 25 degC at 9600 baud but my VB program is either configured incorrectly or it can't keep up. For example if Arduino is sending a stream of 25.16s my program might pick out 5.16 or "" or 0.16.
A quick fix would be if I had a way to ignore any value that doesn't convert to a double and repeat until it gets a valid string without breaking the program. Then get rid of values that are too small as well. I don't know how to do the first part but it's what I think I need to do.
I'm new to programming so if my programs are totally wrong, please forgive me.
Also I would love any feedback on my two programs, even if it isn't relevant to my problem.
Here is my Arduino code just in case it is wrong. I'm using a digital thermometer.
#include <LiquidCrystal.h>
#include <OneWire.h>
int DS18S20_Pin = 9;
int buttonPin = 8;
int ledPin = 7;
OneWire ds(DS18S20_Pin);
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int backLight = 13;
int val = 0;
int oldVal = 0;
int state = 0;
void setup()
{
Serial.begin(9600);
pinMode(backLight, OUTPUT);
pinMode(buttonPin, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(backLight, HIGH);
lcd.begin(16,2);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Temperature");
}
void loop(void)
{
val = digitalRead(buttonPin);
if (val == HIGH && oldVal == LOW)
{
state = 1 - state;
delay(10);
}
oldVal = val;
if (state == 1)
{
float temperature = getTemp();
temperature = temperature*(9/5)+32;
lcd.setCursor(0,1);
lcd.print(temperature);
Serial.println(temperature);
lcd.setCursor(6,1);
lcd.print(char(223));
lcd.setCursor(7,1);
lcd.print("F");
digitalWrite(ledPin, LOW);
delay(10);
}
else
{
float temperature = getTemp();
lcd.setCursor(0,1);
lcd.print(temperature);
Serial.println(temperature);
lcd.setCursor(6,1);
lcd.print(char(223));
lcd.setCursor(7,1);
lcd.print("C");
digitalWrite(ledPin, HIGH);
delay(10);
}
}
float getTemp()
{
byte data[9];
byte addr[8];
if ( !ds.search(addr)) {
ds.reset_search();
return -1000;
}
if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.print("CRC is not valid!\n");
return -1000;
}
if ( addr[0] != 0x10 && addr[0] != 0x28) {
Serial.print("Device is not recognized");
return -1000;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1);
byte present = ds.reset();
ds.select(addr);
ds.write(0xBE);
for (int i = 0; i < 9; i++) {
data[i] = ds.read();
}
ds.reset_search();
byte MSB = data[1];
byte LSB = data[0];
float tempRead = ((MSB << 8) | LSB);
float TemperatureSum = tempRead / 16;
return TemperatureSum;
}
Here is my VB code which is probably where my mistake is:
Imports System.Windows.Forms.DataVisualization.Charting
Imports System
Imports System.ComponentModel
Imports System.Threading
Imports System.IO.Ports
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim Time As Long = 0
Dim line As String = ""
Dim Chart1 As New Chart
If (SerialPort1.IsOpen = True) Then
SerialPort1.Close()
SerialPort1.DiscardInBuffer()
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim i As Long = 0
Dim temp As Double = 0
Dim tempArray(0) As Double
Dim length As Long = 0
Dim message1 As String = ""
Chart1.ChartAreas(0).AxisX.Maximum = 20
Chart1.ChartAreas(0).AxisX.Minimum = 0
Chart1.ChartAreas(0).AxisY.Maximum = 20
Chart1.ChartAreas(0).AxisY.Minimum = 0
Chart1.Series(0).ChartType = DataVisualization.Charting.SeriesChartType.Line
SerialPort1.PortName = "COM3"
SerialPort1.BaudRate = 9600
SerialPort1.Parity = IO.Ports.Parity.None
SerialPort1.DataBits = 8
SerialPort1.StopBits = IO.Ports.StopBits.One
SerialPort1.Open()
While (SerialPort1.IsOpen())
If SerialPort1.BytesToRead() = 0 Then
SerialPort1.DiscardInBuffer()
Else
message1 = SerialPort1.ReadLine()
SerialPort1.DiscardInBuffer()
If message1 = "" Then
While message1 = ""
message1 = SerialPort1.ReadLine()
SerialPort1.DiscardInBuffer()
End While
End If
If message1 = " " Then
While message1 = " "
message1 = SerialPort1.ReadLine()
SerialPort1.DiscardInBuffer()
End While
End If
Try
temp = Convert.ToDouble(message1)
Catch ex As FormatException
End Try
tempArray(i) = temp
length = UBound(tempArray)
If length >= 0 Then
ReDim Preserve tempArray(length + 1)
End If
Label1.text = message1
Chart1.Series(0).Points.Add(tempArray(i))
If (tempArray(i) > Chart1.ChartAreas(0).AxisY.Maximum) Then
Chart1.ChartAreas(0).AxisY.Maximum = tempArray(i)
End If
Chart1.Series(0).Points.AddY(tempArray(i))
If Chart1.Series(0).Points.Count = 30 Then
Chart1.Series(0).Points.RemoveAt(0)
Chart1.ChartAreas(0).AxisX.Maximum = UBound(tempArray)
Chart1.ChartAreas(0).AxisX.Minimum = UBound(tempArray) - 30
End If
i += 1
End If
End While
MessageBox.Show("Session has ended.")
End Sub
End Class
Thanks Kyle