Pages: [1]   Go Down
Author Topic: Old Standard Firmata - value Triger LED help  (Read 958 times)
0 Members and 1 Guest are viewing this topic.
Port Elizabeth, South Africa
Offline Offline
Newbie
*
Karma: 0
Posts: 48
Arduino user South Africa
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Good day

I am trying to make the led on PIN13 light up when the value of A0 drops below a certain value.
I am using the Firmata VB app in Windows 7 and use a Arduino Deumilaueve connected via USB.

The app works fine and displays the value in the A0 Progress bar on the left, but the code is way to advanced to pinpoint where the code must go, as I can not see the A0 Pin code.

Here is a link to the app I am usinghttp://www.acraigie.com/programming/firmatavb/default.html, and I am using a voltage divider to get the analog value of around 856, and would like the LED on pin 13 to light up when the value drops to 855 or below.

Here is the Old Standard Firmata Scetch, as the Standard Firmata Scetch does not work for me.
Code:
/*
  Copyright (C) 2006-2008 Hans-Christoph Steiner.  All rights reserved.
 
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
 
  See file LICENSE.txt for further informations on licensing terms.
 */

/*
 * This is an old version of StandardFirmata (v2.0).  It is kept here because
 * its the last version that works on an ATMEGA8 chip.  Also, it can be used
 * for host software that has not been updated to a newer version of the
 * protocol.  It also uses the old baud rate of 115200 rather than 57600.
 */

#include <EEPROM.h>
#include <Firmata.h>

/*==============================================================================
 * GLOBAL VARIABLES
 *============================================================================*/

/* analog inputs */
int analogInputsToReport = 0; // bitwise array to store pin reporting
int analogPin = 0; // counter for reading analog pins

/* digital pins */
byte reportPINs[TOTAL_PORTS];   // PIN == input port
byte previousPINs[TOTAL_PORTS]; // PIN == input port
byte pinStatus[TOTAL_PINS]; // store pin status, default OUTPUT
byte portStatus[TOTAL_PORTS];

/* timer variables */
unsigned long currentMillis;     // store the current value from millis()
unsigned long previousMillis;    // for comparison with currentMillis


/*==============================================================================
 * FUNCTIONS                                                               
 *============================================================================*/

void outputPort(byte portNumber, byte portValue)
{
  portValue = portValue &~ portStatus[portNumber];
  if(previousPINs[portNumber] != portValue) {
        Firmata.sendDigitalPort(portNumber, portValue);
        previousPINs[portNumber] = portValue;
        Firmata.sendDigitalPort(portNumber, portValue);
    }
}

/* -----------------------------------------------------------------------------
 * check all the active digital inputs for change of state, then add any events
 * to the Serial output queue using Serial.print() */
void checkDigitalInputs(void)
{
    byte i, tmp;
    for(i=0; i < TOTAL_PORTS; i++) {
        if(reportPINs[i]) {
            switch(i) {
            case 0: outputPort(0, PIND &~ B00000011); break; // ignore Rx/Tx 0/1
            case 1: outputPort(1, PINB); break;
            case 2: outputPort(2, PINC); break;
            }
        }
    }
}

// -----------------------------------------------------------------------------
/* sets the pin mode to the correct state and sets the relevant bits in the
 * two bit-arrays that track Digital I/O and PWM status
 */
void setPinModeCallback(byte pin, int mode) {
    byte port = 0;
    byte offset = 0;

    if (pin < 8) {
      port = 0;
      offset = 0;
    } else if (pin < 14) {
      port = 1;
      offset = 8;     
    } else if (pin < 22) {
      port = 2;
      offset = 14;
    }

    if(pin > 1) { // ignore RxTx (pins 0 and 1)
        pinStatus[pin] = mode;
        switch(mode) {
        case INPUT:
            pinMode(pin, INPUT);
            portStatus[port] = portStatus[port] &~ (1 << (pin - offset));
            break;
        case OUTPUT:
            digitalWrite(pin, LOW); // disable PWM
        case PWM:
            pinMode(pin, OUTPUT);
            portStatus[port] = portStatus[port] | (1 << (pin - offset));
            break;
        //case ANALOG: // TODO figure this out
        default:
            Firmata.sendString("");
        }
        // TODO: save status to EEPROM here, if changed
    }
}

void analogWriteCallback(byte pin, int value)
{
    setPinModeCallback(pin,PWM);
    analogWrite(pin, value);
}

void digitalWriteCallback(byte port, int value)
{
    switch(port) {
    case 0: // pins 2-7 (don't change Rx/Tx, pins 0 and 1)
        // 0xFF03 == B1111111100000011    0x03 == B00000011
        PORTD = (value &~ 0xFF03) | (PORTD & 0x03);
        break;
    case 1: // pins 8-13 (14,15 are disabled for the crystal)
        PORTB = (byte)value;
        break;
    case 2: // analog pins used as digital
        PORTC = (byte)value;
        break;
    }
}

// -----------------------------------------------------------------------------
/* sets bits in a bit array (int) to toggle the reporting of the analogIns
 */
//void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
//}
void reportAnalogCallback(byte pin, int value)
{
    if(value == 0) {
        analogInputsToReport = analogInputsToReport &~ (1 << pin);
    }
    else { // everything but 0 enables reporting of that pin
        analogInputsToReport = analogInputsToReport | (1 << pin);
    }
    // TODO: save status to EEPROM here, if changed
}

void reportDigitalCallback(byte port, int value)
{
    reportPINs[port] = (byte)value;
    if(port == 2) // turn off analog reporting when used as digital
        analogInputsToReport = 0;
}

/*==============================================================================
 * SETUP()
 *============================================================================*/
void setup()
{
    byte i;

    Firmata.setFirmwareVersion(2, 0);

    Firmata.attach(ANALOG_MESSAGE, analogWriteCallback);
    Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
    Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
    Firmata.attach(REPORT_DIGITAL, reportDigitalCallback);
    Firmata.attach(SET_PIN_MODE, setPinModeCallback);

    portStatus[0] = B00000011;  // ignore Tx/RX pins
    portStatus[1] = B11000000;  // ignore 14/15 pins
    portStatus[2] = B00000000;

//    for(i=0; i<TOTAL_PINS; ++i) { // TODO make this work with analogs
    for(i=0; i<14; ++i) {
        setPinModeCallback(i,OUTPUT);
    }
    // set all outputs to 0 to make sure internal pull-up resistors are off
    PORTB = 0; // pins 8-15
    PORTC = 0; // analog port
    PORTD = 0; // pins 0-7

    // TODO rethink the init, perhaps it should report analog on default
    for(i=0; i<TOTAL_PORTS; ++i) {
        reportPINs[i] = false;
    }
    // TODO: load state from EEPROM here

    /* send digital inputs here, if enabled, to set the initial state on the
     * host computer, since once in the loop(), this firmware will only send
     * digital data on change. */
    if(reportPINs[0]) outputPort(0, PIND &~ B00000011); // ignore Rx/Tx 0/1
    if(reportPINs[1]) outputPort(1, PINB);
    if(reportPINs[2]) outputPort(2, PINC);

    Firmata.begin(115200);
}

/*==============================================================================
 * LOOP()
 *============================================================================*/
void loop()
{
/* DIGITALREAD - as fast as possible, check for changes and output them to the
 * FTDI buffer using Serial.print()  */
    checkDigitalInputs(); 
    currentMillis = millis();
    if(currentMillis - previousMillis > 20) { 
        previousMillis += 20;     // run this every 20ms
        /* SERIALREAD - Serial.read() uses a 128 byte circular buffer, so handle
         * all serialReads at once, i.e. empty the buffer */
        while(Firmata.available())
            Firmata.processInput();
        /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
         * 60 bytes. use a timer to sending an event character every 4 ms to
         * trigger the buffer to dump. */

        /* ANALOGREAD - right after the event character, do all of the
         * analogReads().  These only need to be done every 4ms. */
        for(analogPin=0;analogPin<TOTAL_ANALOG_PINS;analogPin++) {
            if( analogInputsToReport & (1 << analogPin) ) {
                Firmata.sendAnalog(analogPin, analogRead(analogPin));
            }
        }
    }
}

Please help me with this.

Thank you.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You need to have your VB application set the mode of the pin (13) to OUTPUT, then use digitalWrite() to set the pin to HIGH or LOW.

Quote
but the code is way to advanced
Which code? You do not need to make any changes to the OldStandardFirmata sketch.

If it's the VB code that is too advanced, we can't tell you how to change that, since you didn't post that code.
Logged

Port Elizabeth, South Africa
Offline Offline
Newbie
*
Karma: 0
Posts: 48
Arduino user South Africa
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

VB Code.
Code:
' Arduino <> Firmata <> Visual Basic .NET
' ArduinoFirmataVBExtended
' Program to demonstrate the use of FirmataVB, DigitalPinControl
' and AnalogPinControl components
' The program communicates with an Arduino Diecimila
' running the freely available Standard Firmata Library (see links below
' for info on Firmata)
' Copyright (c) 2009 Andrew Craigie. All rights reserved
' http://www.acraigie.com

'This program is free software: you can redistribute it and/or modify
'it under the terms of the GNU General Public License as published by
'the Free Software Foundation, either version 3 of the License, or
'(at your option) any later version.

'This program is distributed in the hope that it will be useful,
'but WITHOUT ANY WARRANTY; without even the implied warranty of
'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'GNU General Public License for more details.

'You should have received a copy of the GNU General Public License
'along with this program.  If not, see <http://www.gnu.org/licenses/>.

'
' Firmata is a generic protocol for communicating with microcontrollers
' from software on a host computer
' Firmata library http://www.firmata.org and http://sourceforge.net/projects/firmata

Public Class Form1
    Private DigitalPins As New Hashtable
    Private AnalogPins As New Hashtable
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        FillCOMsCombo()
        FillBaudCombo()
        UpdateToolStrip()

        For Each ctrl As System.Windows.Forms.Control In Me.Controls
            Dim ThisCtrl As Firmata.DigitalPinControl = Nothing
            If TypeOf ctrl Is Firmata.DigitalPinControl Then
                ThisCtrl = ctrl
                DigitalPins.Add(CStr(ThisCtrl.PinNumber), ThisCtrl)
                AddHandler ThisCtrl.DigitalSend, AddressOf DigitalPinControl_DigitalSend
                AddHandler ThisCtrl.PinMode_Changed, AddressOf DigitalPinControl_PinMode_Changed
                AddHandler ThisCtrl.PWMSend, AddressOf DigitalPinControl_PWMSend
            End If
        Next

        For Each ctrl As System.Windows.Forms.Control In Me.Controls
            Dim ThisCtrl As Firmata.AnalogPinControl = Nothing
            If TypeOf ctrl Is Firmata.AnalogPinControl Then
                ThisCtrl = ctrl
                AnalogPins.Add(CStr(ThisCtrl.PinNumber), ThisCtrl)
                AddHandler ThisCtrl.AnalogOnOff_Changed, AddressOf AnalogPinControl_AnalogOnOff_Changed
            End If

        Next

        'If FirmataVB1 IsNot Nothing Then
        'FirmataVB1.Connect("COM4", 115200)
        'End If

    End Sub

    Private Sub DigitalPinControl_DigitalSend(ByVal PinNumber As Integer, ByVal value As Integer)
        FirmataVB1.DigitalWrite(PinNumber, value)
    End Sub

    Private Sub DigitalPinControl_PinMode_Changed(ByVal PinNumber As Integer, ByVal Mode As Firmata.DigitalPinControl.PinModes)
        If FirmataVB1.PortOpen = True Then
            FirmataVB1.PinMode(PinNumber, Mode)
        End If
    End Sub

    Private Sub DigitalPinControl_PWMSend(ByVal PinNumber As Integer, ByVal PWMValue As Integer)
        FirmataVB1.AnalogWrite(PinNumber, PWMValue)
    End Sub

    Private Sub AnalogPinControl_AnalogOnOff_Changed(ByVal PinNumber As Integer, ByVal OnOff As Integer)
        FirmataVB1.AnalogPinReport(PinNumber, OnOff)

    End Sub

    Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
        If FirmataVB1.PortOpen = True Then
            FirmataVB1.Disconnect()
        End If
        Me.Close()
    End Sub

    Private Sub cbPort_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cbPort1.CheckedChanged, cbPort0.CheckedChanged
        Dim cbOnOff As System.Windows.Forms.CheckBox
        cbOnOff = sender
        Dim portNumber As Integer
        portNumber = CInt(cbOnOff.Tag)
        Dim OnOff As Integer = 0

        If cbOnOff.Checked = True Then
            cbOnOff.Text = "On"
            OnOff = 1
            FirmataVB1.DigitalPortReport(portNumber, OnOff)
            For Each de As DictionaryEntry In DigitalPins
                Dim ctrl As Firmata.DigitalPinControl
                ctrl = DigitalPins(de.Key)
                If ctrl.Port = portNumber Then
                    ctrl.MyPortReporting = True
                End If
            Next
        Else
            cbOnOff.Text = "Off"
            OnOff = 0
            FirmataVB1.DigitalPortReport(portNumber, OnOff)
            For Each de As DictionaryEntry In DigitalPins
                Dim ctrl As Firmata.DigitalPinControl
                ctrl = DigitalPins(de.Key)
                If ctrl.Port = portNumber Then
                    ctrl.MyPortReporting = False
                End If
            Next
        End If
    End Sub

    Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
        ' Dispose of components then
        If Not FirmataVB1 Is Nothing Then
            FirmataVB1.Disconnect()
            FirmataVB1 = Nothing
        End If
        Me.Close()
    End Sub

    Private Sub AboutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutToolStripMenuItem.Click
        System.Diagnostics.Process.Start("http://www.acraigie.com/programming/firmatavb/default.html")
    End Sub

    Private Sub HelpToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles HelpToolStripMenuItem1.Click
        System.Diagnostics.Process.Start("http://www.acraigie.com/programming/firmatavb/default.html")
    End Sub

    Public Sub FillCOMsCombo()
        tscbCOMList.Items.AddRange(FirmataVB1.COMPortList())
        tscbCOMList.Text = Firmata.FirmataVB.DEFAULT_COM_PORT
        ' or set it to the COM port property of this instance of FirmataVB ...
        ' tscbCOMList.Text = FirmataVB1.PortName
    End Sub

    Public Sub FillBaudCombo()
        tscbBaud.Items.AddRange(FirmataVB1.CommonBaudRates())
        tscbBaud.Text = Firmata.FirmataVB.DEFAULT_BAUD_RATE
        ' or set it to the Baud property of this instance of FirmataVB
        ' tscbBaud.text = FirmataVB1.Baud
    End Sub

    Private Sub tscbCOMList_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tscbCOMList.Click
        If tscbCOMList.Text <> "" Then
            FirmataVB1.COMPortName = tscbCOMList.Text
        End If
    End Sub

    Private Sub tscbBaud_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tscbBaud.Click
        If tscbBaud.Text <> "" Then
            FirmataVB1.Baud = CInt(tscbBaud.Text)
        End If
    End Sub

    Private Sub tsbtnConnection_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsbtnConnection.Click
        If tsbtnConnection.Text = "Connect" Then
            FirmataVB1.Connect(tscbCOMList.Text, CInt(tscbBaud.Text))
            FirmataVB1.QueryVersion()
            UpdateToolStrip()
        Else
            FirmataVB1.Disconnect()
            UpdateToolStrip()
        End If
    End Sub
   
Logged

Port Elizabeth, South Africa
Offline Offline
Newbie
*
Karma: 0
Posts: 48
Arduino user South Africa
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry had to split code, message too long

Code:
Public Sub UpdateToolStrip()
        If (tscbCOMList.Text <> "" And tscbBaud.Text <> "") And FirmataVB1.PortOpen() = False Then
            tsbtnConnection.Enabled = True
            tsbtnConnection.Text = "Connect"
            tslblStatus.Text = ""
            tslblStatus.BackColor = Color.Green
            tscbCOMList.Enabled = True
            tscbBaud.Enabled = True
        ElseIf FirmataVB1.PortOpen() = True Then
            tsbtnConnection.Enabled = True
            tsbtnConnection.Text = "Disconnect"
            ' Need a property of FirmataVB to get port name in use
            tslblStatus.Text = FirmataVB1.PortName() & " is connected"
            tslblStatus.BackColor = Color.LightPink
            tscbCOMList.Enabled = False
            tscbBaud.Enabled = False
        Else
            tsbtnConnection.Enabled = False
            tsbtnConnection.Text = "Connect"
            tslblStatus.Text = ""
            tslblStatus.BackColor = Color.Green
            tscbCOMList.Enabled = True
            tscbBaud.Enabled = True
        End If
    End Sub

    ' Handles clicking the Set all to Inputs button
    ' cycles through Pins hashtable and sends a set input message
    ' to the board for each pin. Here for convenience when
    ' testing   
    Private Sub btnSetAllInputs_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSetAllInputs.Click
        For Each de As DictionaryEntry In DigitalPins
            FirmataVB1.PinMode(CInt(de.Key), Firmata.FirmataVB.INPUT)
        Next
    End Sub

    ' Handles clicking of either Port Reporting on/off checkboxes
    ' Firmata V 2.0 does not support digital reporting of individual
    ' pins
    Private Sub cbPort0_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cbPort0.CheckedChanged, cbPort1.CheckedChanged
        Dim digitalReportOnOff As System.Windows.Forms.CheckBox
        digitalReportOnOff = sender

        Dim portNumber As Integer
        portNumber = CInt(digitalReportOnOff.Tag)
        Dim onOff As Integer = 0

        If digitalReportOnOff.Checked = True Then
            digitalReportOnOff.Text = "On"
            onOff = 1
            FirmataVB1.DigitalPortReport(portNumber, onOff)
            ' Set LED graphic in port to active
            For Each de As DictionaryEntry In DigitalPins
                Dim ctrl As Firmata.DigitalPinControl
                ctrl = DigitalPins(de.Key)
                If ctrl.Port = portNumber Then
                    ctrl.MyPortReporting = True
                End If
            Next
        Else
            digitalReportOnOff.Text = "Off"
            onOff = 0
            FirmataVB1.DigitalPortReport(portNumber, onOff)
            ' Set LED graphic in port to dimmed
            For Each de As DictionaryEntry In DigitalPins
                Dim ctrl As Firmata.DigitalPinControl
                ctrl = DigitalPins(de.Key)
                If ctrl.Port = portNumber Then
                    ctrl.MyPortReporting = False
                End If
            Next
        End If
    End Sub

    ' Handles FirmataVB_AnalogMessaageReceived
    Private Sub FirmataVB1_AnalogMessageReceieved(ByVal pin As Integer, ByVal value As Integer) Handles FirmataVB1.AnalogMessageReceieved
        Dim AnalogPin As Firmata.AnalogPinControl
        AnalogPin = AnalogPins(CStr(pin))
        ' Call the SetAnalogValue sub rather than
        ' try to set the AnalogValue property directly
        ' SetAnalogValue has code in it to make the
        ' call in a threadsafe way
        AnalogPin.SetAnalogValue(value)
        ' NOT - AnalogPin.AnalogValue = value

    End Sub

    ' Handles FirmataVB_DigitalMessageReceieved.
    Private Sub FirmataVB1_DigitalMessageReceieved(ByVal portNumber As Integer, ByVal portData As Integer) Handles FirmataVB1.DigitalMessageReceieved
        ' We could simply do a DigitalRead for each DigitalControl but
        ' at least only doing a port at a time saves some time
        ' Ideally we want an event that is fired by FirmataVB that
        ' sends as it's arguments the PinNumber and On/Off
        Select Case portNumber
            Case 0 ' Cycle through Port 0 pins - pins 2 to 7. (Pins 0/1 are RX/TX pins)
                For i As Integer = 2 To 7 ' Need to come up with a simple way of setting the range from the
                    ' DigitalControls on the Form and the board being used
                    Dim value As Integer
                    value = FirmataVB1.DigitalRead(i)
                    Dim PinControl As Firmata.DigitalPinControl
                    PinControl = DigitalPins(CStr(i))
                    Select Case value
                        Case 1
                            PinControl.LED = Firmata.DigitalPinControl.LEDStates.LED_ON
                        Case 0
                            If PinControl.PinMode = Firmata.DigitalPinControl.PinModes.INPUT Then
                                PinControl.LED = Firmata.DigitalPinControl.LEDStates.LED_OFF
                            Else
                                PinControl.LED = Firmata.DigitalPinControl.LEDStates.LED_DIM
                            End If
                    End Select
                Next
            Case 1 ' Cycle through Port 1 pins - pins 8 - 12. (Pin 13 is LED pin)
                For i As Integer = 8 To 12
                    Dim value As Integer
                    value = FirmataVB1.DigitalRead(i)
                    Dim PinControl As Firmata.DigitalPinControl
                    PinControl = DigitalPins(CStr(i))
                    Select Case value
                        Case 1
                            PinControl.LED = Firmata.DigitalPinControl.LEDStates.LED_ON
                        Case 0
                            If PinControl.PinMode = Firmata.DigitalPinControl.PinModes.INPUT Then
                                PinControl.LED = Firmata.DigitalPinControl.LEDStates.LED_OFF
                            Else
                                PinControl.LED = Firmata.DigitalPinControl.LEDStates.LED_DIM
                            End If

                    End Select
                Next
        End Select

    End Sub

    Private Sub FirmataVB1_VersionInfoReceieved(ByVal majorVersion As Integer, ByVal minorVersion As Integer) Handles FirmataVB1.VersionInfoReceieved
        ' Update label or other control in thread safe way
        ' to display Major and Minor version info
        Debug.Print("Majorversion: " & majorVersion & " Minorversion: " & minorVersion)
    End Sub

    Private Sub ToolStripLabel2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripLabel2.Click

    End Sub
End Class
Logged

Port Elizabeth, South Africa
Offline Offline
Newbie
*
Karma: 0
Posts: 48
Arduino user South Africa
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is a picture of the app showing A0 and other Analog & Digital Controls.

Logged

Pages: [1]   Go Up
Jump to: