B4J app for measuring voltage and frequency using Arduino Nano or Uno. The frequency is counted over 1 second by dividing the 16MHz crystal, the ATMEGA328 can count up to 6MHz.
The Arduino connects to the PC via USB.
The Arduino connects to the PC via USB.
B4X:
Sub Process_Globals
Private fx As JFX
Private MainForm As Form
Private xui As XUI
Private sp As Serial
Private astream As AsyncStreams
Private cmb1 As ComboBox
Private Label1 As Label
Private angle As Double = 40
Private Canvas1 As Canvas
Private Pane1 As Pane
Private lblPeriod As Label
Private lblFreq As Label
Private lblVolt As Label
Private Button1 As Button
End Sub
Sub AppStart (Form1 As Form, Args() As String)
MainForm = Form1
MainForm.RootPane.LoadLayout("Layout1")
MainForm.Show
sp.Initialize("")
cmb1.Items.AddAll(sp.ListPorts)
Canvas1.DrawLine(100,100,100 - 80 * Cos(angle * 3.14 / 180),100 - 80 * Sin(angle * 3.14 / 180),fx.Colors.Black, 1dip)
drawVM
End Sub
Sub cmb1_SelectedIndexChanged(Index As Int, Value As Object)
Try
sp.Open(cmb1.Value)
sp.SetParams(9600,8,1,0)
astream.Initialize(sp.GetInputStream, sp.GetOutputStream, "astream")
Label1.Text = "Port Opened"
Catch
Label1.Text = "Port is busy"
Log("Port error")
End Try
End Sub
Sub AStream_NewData (Buffer() As Byte)
Dim freq As Double
Dim volt, period As Double
Dim u4, u3, u2, u1 As Int
If Buffer.Length > 5 Then
If Buffer(1) < 0 Then u1=Buffer(1)+256 Else u1=Buffer(1) 'convert to unsigned byte
If Buffer(2) < 0 Then u2=Buffer(2)+256 Else u2=Buffer(2) 'convert to unsigned byte
If Buffer(3) < 0 Then u3=Buffer(3)+256 Else u3=Buffer(3)
freq=u1*65536 + u2*256 + u3
lblFreq.Text=NumberFormat(freq,1,0)
period=1000000 / freq
lblPeriod.Text=NumberFormat(period,1,1)
Canvas1.DrawRect(10,10,180,180,fx.Colors.White,True,0)
drawVM
If Buffer(4) < 0 Then u4=Buffer(4)+256 Else u4=Buffer(4) 'convert to unsigned byte
volt=(Buffer(5)*256 + u4) / 1023 * 5
lblVolt.text=NumberFormat(volt,1,3) & " V"
angle = (40 + volt * 20) * 3.1415 / 180 'analogue meter
Canvas1.DrawLine(100,100,100 - 80 * Cos(angle),100 - 80 * Sin(angle),fx.Colors.Black, 1dip)
End If
End Sub
Sub drawVM
For i=0 To 5
Canvas1.DrawLine(100-80*Cos((i*20+40)*3.14/180),100-80*Sin((i*20+40)*3.14/180),100-70*Cos((i*20+40)*3.14/180) _
,100-70*Sin((i*20+40)*3.14/180),fx.Colors.Black, 1dip)
Next
End Sub
Sub Button1_Click
cmb1.Items.Clear
cmb1.Items.AddAll(sp.ListPorts)
End Sub
Sub MainForm_Closed
'sp.Close
End Sub
B4X:
Sub Process_Globals
Public Serial1 As Serial
Private AStream As AsyncStreams
Public anaA0 As Pin
Public out6 As Pin
Public out9 As Pin
Public out3 As Pin
Public in4 As Pin
Public in5 As Pin
Public freq As UInt
Public overf As Byte
End Sub
Private Sub AppStart
Serial1.Initialize(9600)
AStream.Initialize(Serial1.Stream, "Astream_NewData", "Astream_Error")
RunNative ("setTimers",Null)
anaA0.Initialize(anaA0.A0, anaA0.MODE_INPUT)
out6.Initialize(6, out6.MODE_OUTPUT)
out9.Initialize(9, out9.MODE_OUTPUT)
out3.Initialize(3, out3.MODE_OUTPUT)
in4.Initialize(4, in4.MODE_INPUT)
in5.Initialize(5, in5.MODE_INPUT)
counter
End Sub
Private Sub counter
Private ps(6), freqH, freqL As Byte
Private i=True As Boolean
Do While i=True
Do While out6.DigitalRead=True
Loop
Do While out6.DigitalRead=False 'wait for start of 1 sec
Loop
overf=0
RunNative ("count",Null)
Do While out6.DigitalRead=True
RunNative ("count2",Null)
Loop
RunNative ("count3",Null)
freqH = freq / 256
freqL = freq
ps(0)=50
ps(1)=overf
ps(2)=freqH
ps(3)=freqL
ps(4)=anaA0.AnalogRead
ps(5)=anaA0.AnalogRead / 256
AStream.Write(ps)
Loop
End Sub
Sub Astream_NewData (Buffer() As Byte)
End Sub
Sub AStream_Error
Log("error")
End Sub
#if C
void setTimers(B4R::Object* o)
{
//set timer0 in=250Hz out=1Hz
OCR0A = 249;
TCCR0A=0b1000011;
TCCR0B=0b1110; // PWM mode, input T0 pin D4
// set timer2 in=16MHz out=250Hz
OCR2A =249;
OCR2B = 125;
TCCR2A=0b110011; //output B in phase, fast PWM mode
TCCR2B=0b1110; // set prescaler to 256 and start the timer
// set timer1
OCR1A = 32767; //32768 counts
TCCR1A = 0b1000011;
TCCR1B = 0b11110; //input pin D5
}
#End if
#if C
void count(B4R::Object* o)
{
TIFR1 |= _BV(1); //reset interrupt
OCR1A = 65535; //32767
TCNT1=0;
}
#End if
#if C
void count2(B4R::Object* o){
if(TIFR1 & _BV(1)) {(b4r_main::_overf)=(b4r_main::_overf)+1; TIFR1 |= _BV(1);}
}
#End if
#if C
void count3(B4R::Object* o){
(b4r_main::_freq) = TCNT1 ;
}
#End if
Attachments
Last edited: