Share My Creation Frequency Counter for PC

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.
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

  • counter_b4j.zip
    3.3 KB · Views: 227
  • vf_meter_b4r.zip
    1.5 KB · Views: 232
  • vf-meter405.png
    vf-meter405.png
    20.6 KB · Views: 1,539
  • vf-meter.png
    vf-meter.png
    2.5 KB · Views: 208
Last edited:
Top