简介
我在第一次使用Arduino 2009板的文章中,我描述{A}接口使用Visual Basic。
我已经开发板和Visual Basic代码给一个相当实用的室内气象站的。整体运作{S0}
阿尔杜伊诺2009年作为一个独立的气象站。它不显示的数据。它可以独立运作了好几个月。样品传感器的RAM满之前。 RAM的样本存储在SD卡的一个部门。最后,一年的天气样品可以存储在SD卡上。
每个PC连接时,任何不保存部门上传到计算机的硬盘驱动器上的文件。然后,它可以显示使用电脑的显示所有的设施。
的中心思想是,该委员会有加盖的日期和时间,它被记录每张SD卡部门的文件的副本。Arduino的室内气象站
该程序的活动图:
Arduino的IDE中使用C,并为这项活动图的实际的方案很简单。
SD卡目前的部门举行EEPROM,以便在断电或复位,可重复使用。阿尔杜伊诺一类的EEPROM只允许读取和写入的字节。要读长(32字节在Arduino的),需要完成一些工作:inline void ready()
{
unsigned long lastblock = 0; //the last block number saved in the sd card
unsigned long tempblock = 0;
tempblock = EEPROM.read(0); // remember the LSB of the last saved block
lastblock |= tempblock;
tempblock = EEPROM.read(1); // remember the next LSB of the last saved block
lastblock |= tempblock << 8;
tempblock = EEPROM.read(2); // remember the next LSB of the last saved block
lastblock |= tempblock << 16;
tempblock = EEPROM.read(3); // remember the next MSB of the last saved block
lastblock |= tempblock << 24;
Serial.println("ready"); //send computer the ready to reset message
Serial.println(lastblock); //send computer the last saved block number
delay(10000); //every 10 seconds
}//end of ready
阿尔杜伊诺不会有一个类读写SD卡,所以我写我自己。这是h文件中。:{C}
所以,当我们需要保存的数据的部门,我们:
PC程序启动inline void lastblocksave()
{
unsigned int e = 0; //the error code from the sd card
e = SDCARD.writeblock(currentblock); //save this 256 block of integer data
while (e != 0) //cant continue if sd card not working
{
Serial.println("writesderror"); //send computer sd card error
Serial.println(e); //send computer the error number
digitalWrite(8, HIGH); //turn led on to show sd card error
delay(10000); //every 10 seconds
}//end of sd card not working
currentblock +=1; //go to the next block in sd card
EEPROM.write(0,currentblock); //write the LSB of saved block to EEPROM
EEPROM.write(1,currentblock >> 8); //write the next LSB of saved block to EEPROM
EEPROM.write(2,currentblock >> 16); //write the next LSB of saved block to EEPROM
EEPROM.write(3,currentblock >> 24); //write the MSB of saved block to EEPROM
ramaddress = 0; //we can now start again to save samples in RAM
}//end of sd save
PC程序采用的是微软的Visual Basic速成版IDE。
时显示加载程序,它被激活之前,我们创建一个启动的形式已上传数据样本的所有例程。Private Sub ArduinoWeather_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim f As New showstart
f.ShowDialog() 'startup form to connect to arduino
While My.Computer.FileSystem.FileExists(cd & "\" & last_sector)
last_sector += 1 'find the next block
End While
If My.Computer.FileSystem.FileExists(cd & "\archive") Then
Dim st As Stream = File.Open(cd & "\archive", FileMode.Open, FileAccess.Read)
Dim br As New BinaryReader(st) 'to get samples from stream
Try
Dim n As Integer = 0 'a counter
Do
archived(n) = br.ReadInt64()
archivedisplay.Items.Add(archived(n))
If archived(n) > lastblock Then lastblock = archived(n)
n += 1 'we get the largest archive block
If n = 100 Then Exit Do 'no more room
Loop
Catch ex As Exception 'exception of none left
Finally
br.Close() 'must close
st.Close()
End Try 'exit try when all read
End If
fill_buffers() 'get all the samples into thir buffers
If overflow.Text = "" Then 'enable displays
Try
com8 = My.Computer.Ports.OpenSerialPort("com8", 9600)
readthread = New Threading.Thread(AddressOf read)
readthread.Start() 'thread runs for whole program
'to get samples every 10 sec
Catch ex As Exception
comdisplay.Text = "no connection" & vbNewLine & _
"or" & vbNewLine & "no communication"
display_noconnect.Enabled = True 'just use a timer to display
End Try
End If
End Sub
启动形式的活动图如下所示:{S2}
本次启动的整个目的是要确保,在SD卡上的每一个部门上的硬盘驱动器,其真正的采样时间记录。我启动一个线程,这是用来上传任何所需的数据。这下面的代码是程序的核心:Dim st As Stream = File.Open(save_sd, FileMode.Create, FileAccess.Write)
Dim bw As New BinaryWriter(st) 'to send samples to stream
For i = 0 To 255 'all old samples
bw.Write(sd_samples(i)) 'send all the samples
Next 'sector stored in file
bw.Write(date_stamp.ToString("F")) 'add date to file
date_stamp = date_stamp.Add(TimeSpan.FromSeconds(850))
bw.Close() 'sends all samples to file
st.Close()
lastblock = j 'we have uploaded one sector
upload = "uploading"
Invoke(New messdelegate(AddressOf showmessage)) 'show the progress
用户将看到一个表单屏幕中心:{S3}
接下来,在用户窗体加载,我们确定的部门文件。然后,归档的文件存储在自己的文件。然后填写相关部门的文件显示缓冲区。
最后,我们启动一个线程将读取新的数据将显示在当前显示的样品。
最后,显示用户的形式是:
PC程序用户表
显示图像生成自己的类。数据传递给类和图像添加到用户窗体。如果显示屏,即尽可能详细,每10秒的样品有其自己的像素时,将充分展示跨度为4小时。平均数据可以给一个最大显示值每4周。
显示的开始时间,可以抵消允许任何4个星期的数据部分。这可以在最高分辨率(10秒每个样品)。
这段代码实现的操作:Private Sub display_all()
Try
Dim Tinterrim_buffer(241919) As Int32 'interim buffer for temperature display
Dim Hinterrim_buffer(241919) As Int32 'interim buffer for humidity display
Dim Ainterrim_buffer(241919) As Int32 'interim buffer for air pressure display
Dim Cdisplay_start_time As DateTime 'the current display start time
Select Case True
Case RadioButton1.Checked
display_span = span_define(0) '4 hours
Case RadioButton2.Checked
display_span = span_define(1) '8 hours
Case RadioButton3.Checked
display_span = span_define(2) '12 hours
Case RadioButton4.Checked
display_span = span_define(3) '24 hours
Case RadioButton5.Checked
display_span = span_define(4) '2 days
Case RadioButton6.Checked
display_span = span_define(5) '4 days
Case RadioButton7.Checked
display_span = span_define(6) '7 days
Case RadioButton8.Checked
display_span = span_define(7) '2 weeks
Case RadioButton9.Checked
display_span = span_define(8) '4 weeks
End Select
For i = 0 To 241919
If i < last_pointer + 1 Then
Tinterrim_buffer(241919 - i) = temp_buffer(last_pointer - i)
Hinterrim_buffer(241919 - i) = humid_buffer(last_pointer - i)
Ainterrim_buffer(241919 - i) = air_buffer(last_pointer - i)
Else
Tinterrim_buffer(241919 - i) = 999999
Hinterrim_buffer(241919 - i) = 999999
Ainterrim_buffer(241919 - i) = 999999
End If
Next
d.display_span_time = TimeSpan.FromMinutes(240 * display_span)
Dim number_display As Integer = _
1440 * display_span - 1 'the width of current span
If cursor_time + number_display < 241920 Then
Cdisplay_start_time = display_start_time.AddDays(-28 * cursor_time / 241919)
Dim counter As Integer = 0
For i = 241919 - cursor_time To 0 _
Step -display_span 'copy working to display
Dim average = 0
For j = 0 To display_span - 1
average += Tinterrim_buffer(i - j)
Next 'straight average of the number of samples required
d.temperature(1439 - counter) = average / display_span
average = 0
For j = 0 To display_span - 1
average += Hinterrim_buffer(i - j)
Next 'straight average of the number of samples required
d.humidity(1439 - counter) = average / display_span
average = 0
For j = 0 To display_span - 1
average += Ainterrim_buffer(i - j)
Next 'straight average of the number of samples required
d.airpressure(1439 - counter) = average / display_span
counter += 1 'we have done one
If counter = 1440 Then Exit For
Next
Else
hasbeenoffset.Text = "selected offset out of range"
cursor_time = 0 'reset the value
End If
d.display_start_time = Cdisplay_start_time
If zoom_TH Or zoom_AR Then
If zoom_TH Then
d.full_temp_hum() 'expand temp humid
Else
d.full_air_rain() 'expand air rain
End If
Else 'normal display
d.scale_temp_hum()
d.scale_air_rain()
End If
Catch ex As Exception
End Try
End Sub
用户窗体可以启动一个文件管理形式:{中六}
下面是归档文件的代码:
电路图气象站Private Sub archivefile_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button5.Click
If My.Computer.FileSystem.FileExists(cd & "\archive") Then
Dim words() As String = archived.Text.Split(vbNewLine)
Dim x = CLng((words.Length - 1))
If archiveblock > CLng(words(words.Length - 2)) + 100 Then
Dim str As Stream = File.Open(cd & "\archive", _
FileMode.Append, FileAccess.Write)
Dim bwr As New BinaryWriter(str) 'to send samples to stream
bwr.Write(archiveblock) 'send all the samples to disk
bwr.Close() 'sends all samples to file
str.Close()
Else
MsgBox("The archived block must be at least" & vbNewLine & _
"one day -that is 100 bigger than last")
End If
Dim st As Stream = File.Open(cd & "\archive", FileMode.Open, FileAccess.Read)
Dim br As New BinaryReader(st) 'to get samples
archived.Text = ""
Try
Do
archived.Text = archived.Text & (br.ReadInt64()) & vbNewLine
Loop
Catch ex As Exception 'exception of none left
Finally
br.Close() 'must close
st.Close()
End Try 'exit try when all read
End If
End Sub