What is this StandardFirmata_ModifiedAll code doing?

I get this full code from here
https://sourceforge.net/projects/arduinovblab/files/VB.NET%20Code/ArduinoFirmata_Lab-alpha%2014-05-18-2012.zip/download
I would like to understand what the code is doing so I can modify it and improve the GUI.

Anyone can explain what this code do?
it drives me crazy to understand it.

...

void setup() 
{
  Firmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);

  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);
  Firmata.attach(START_SYSEX, sysexCallback);
  Firmata.attach(SYSTEM_RESET, systemResetCallback);

  Firmata.begin(57600);
  systemResetCallback();  // reset to default config
}

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

/*==============================================================================
 * LOOP()
 *============================================================================*/
void loop() 
{
  byte pin, analogPin;

  /* DIGITALREAD - as fast as possible, check for changes and output them to the
   * FTDI buffer using Serial.print()  */
  checkDigitalInputs();  

  /* SERIALREAD - processing incoming messagse as soon as possible, while still
   * checking digital inputs.  */
  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. */

  currentMillis = millis();
  if (currentMillis - previousMillis > samplingInterval) {
    previousMillis += samplingInterval;
    /* ANALOGREAD - do all analogReads() at the configured sampling interval */
    for(pin=0; pin<TOTAL_PINS; pin++) {
      if (IS_PIN_ANALOG(pin) && pinConfig[pin] == ANALOG) {
        analogPin = PIN_TO_ANALOG(pin);
        if (analogInputsToReport & (1 << analogPin)) {
          Firmata.sendAnalog(analogPin, analogRead(analogPin));
        }
      }
    }
    // report i2c data for all device with read continuous mode enabled
    if (queryIndex > -1) {
      for (byte i = 0; i < queryIndex + 1; i++) {
        readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
      }
    }
  }
    byte i;
    for (i=0; i<TOTAL_PORTS; i++) {
      sendPort(i, readPort(i, 0xff));
  }
  /* make sure that the FTDI buffer doesn't go over 60 bytes, otherwise you
     get long, random delays.  So only read analogs every 20ms or so */
  currentMillis = millis();
  if(currentMillis - previousMillis > samplingInterval) {
    previousMillis += samplingInterval;
    while(Firmata.available()) {
      Firmata.processInput();
    }
    for(pin = 0; pin < TOTAL_ANALOG_PINS; pin++) {
      analogValue = analogRead(pin);
      if(analogValue != previousAnalogValues[pin]) {
        Firmata.sendAnalog(pin, analogValue); 
        previousAnalogValues[pin] = analogValue;
      }
    }
  }
}

The idea behind Firmata is that you don't need to understand the sketch in order to be able to develop applications in Processing or VB or other languages that operate the Arduino as a dumb device.

I would like to understand what the code is doing so I can modify it and improve the GUI.

The code that you posted a snippet of does not display a GUI, so you are looking at the wrong code.

Thank you PaulS for response,
If you download from the link I gave, then you may get the GUI using Visual Basic.
In the folder you can get Arduino Code and Arduino Firmata VB, where the Arduino Code is going to be uploaded to Arduino UNO device,
the reason I would like to understand the code is because my arduino not UNO but I am using MEGA…
Can you give more suggestion and input ?

PaulS:
The idea behind Firmata is that you don’t need to understand the sketch in order to be able to develop applications in Processing or VB or other languages that operate the Arduino as a dumb device.

I would like to understand what the code is doing so I can modify it and improve the GUI.

The code that you posted a snippet of does not display a GUI, so you are looking at the wrong code.

Hmm, could you explain explicitly what you mean with dumb device?
Why no need to understand the sketch?

the reason I would like to understand the code is because my arduino not UNO but I am using MEGA...

Then you have a relatively major job ahead of you, and you will most definitely need to understand the code. The reason for this is that Firmata currently does not play well with the Mega (which has lot more pins, including more PWM pins, more analog pins) and more timers supporting more servos - none of which Firmata knows about.

No one from the Firmata community seems interested in improving Firmata to work with the Mega, so thank you for volunteering.

Hmm, could you explain explicitly what you mean with dumb device?

I mean that with the Firmata sketch uploaded, the functionality of the Arduino is fixed. It is limited by what the program on the other end tells it to do (read a digital pin, write to a digital pin, read an analog pin, etc.).

It can not also, for instance, run a web server or do timer related things or respond to external interrupts.

Why no need to understand the sketch?

As far as your original intent, modifying a GUI on a PC, there is no need to understand exactly how the Arduino responds to a Firmata-formatted request to read a digital pin or set a PWM value or read an analog pin. All you need to know is that it does.

PaulS:

the reason I would like to understand the code is because my arduino not UNO but I am using MEGA…

Then you have a relatively major job ahead of you, and you will most definitely need to understand the code. The reason for this is that Firmata currently does not play well with the Mega (which has lot more pins, including more PWM pins, more analog pins) and more timers supporting more servos - none of which Firmata knows about.

No one from the Firmata community seems interested in improving Firmata to work with the Mega, so thank you for volunteering.

I feel discourage…Because I do not have any basic on VB and that Arduino Firmata Sketch.
Do you have any recommendation where I should start?

Why no need to understand the sketch?

As far as your original intent, modifying a GUI on a PC, there is no need to understand exactly how the Arduino responds to a Firmata-formatted request to read a digital pin or set a PWM value or read an analog pin. All you need to know is that it does.

Actually, I have my sketch code which has worked well without using VB, just directly from Arduino UNO to 7segment display and sensors.

...

// Variable holding the timer value so far. One for each "Timer"
unsigned long redLED0timer;
unsigned long redLED1timer;
unsigned long redLED2timer;
*/
  
  
  
// Definitions of the 7-bit values for displaying digits
byte g_digits [10];

//Machine Config in integer array
int MachineConfig[3][3];

// Current number being displayed
int g_numberToDisplay = 0;

// Number of shift registers in use
const int g_registers = 4;

// Array of numbers to pass to shift registers
byte g_registerArray [g_registers];

void setup()
{
  //pinMode (redLED0,OUTPUT);
  //pinMode (redLED1,OUTPUT);
  //pinMode (redLED2,OUTPUT);
  
  Serial.begin(9600);
 
  
  pinMode (IRdetectPin0,INPUT);
  pinMode (IRdetectPin1,INPUT);
  pinMode (IRdetectPin2,INPUT);
  
  pinMode (pinCommLatch1,OUTPUT);
  pinMode (pinData1,OUTPUT);
  pinMode (pinClock1,OUTPUT);  
  
  pinMode (switchPin0,INPUT);
  pinMode (switchPin1,INPUT);
  pinMode (switchPin2,INPUT);
  
  //config for line 1
  MachineConfig[0][0]=2;   //pinCommLatch line   1
  MachineConfig[0][1]=5;   //pinData line        1
  MachineConfig[0][2]=8;  //pinClock line       1
 
  //config for line 2
  MachineConfig[1][0]=3;   //pinCommLatch line   2
  MachineConfig[1][1]=6;   //pinData line        2
  MachineConfig[1][2]=9;  //pinClock line       2
  
  //config for line 3
  MachineConfig[2][0]=4;   //pinCommLatch line   3
  MachineConfig[2][1]=7;  //pinClock line       3
  MachineConfig[2][2]=10;  //pinData line        3
  
  // Setup the digits array
  g_digits [0] = 1 + 2 + 4 + 8 + 16 + 32 + 00;
  g_digits [1] = 0 + 2 + 4 + 0 + 00 + 00 + 00;
  g_digits [2] = 1 + 2 + 0 + 8 + 16 + 00 + 64;
  g_digits [3] = 1 + 2 + 4 + 8 + 00 + 00 + 64;         
  g_digits [4] = 0 + 2 + 4 + 0 + 00 + 32 + 64;              
  g_digits [5] = 1 + 0 + 4 + 8 + 00 + 32 + 64;         
  g_digits [6] = 1 + 0 + 4 + 8 + 16 + 32 + 64;
  g_digits [7] = 1 + 2 + 4 + 0 + 00 + 00 + 00;                   
  g_digits [8] = 1 + 2 + 4 + 8 + 16 + 32 + 64;
  g_digits [9] = 1 + 2 + 4 + 8 + 00 + 32 + 64;     
  //for loop 0-2 int
  for(int i=0;i<1;i++){
    sendSerialDatainitial(g_registers, g_registerArray,i);
  }
}

void sendSerialDatainitial(   
  byte registerCount,  // How many shift registers?
  byte *pValueArray,int fromLine)   // Array of bytes with LSByte in array [0]
{ 
    g_registerArray [3] = g_digits [0];
    g_registerArray [2] = g_digits [0];
    g_registerArray [1] = g_digits [0];
    g_registerArray [0] = g_digits [0];
    
    int PINCommLatch=MachineConfig[fromLine][0];
    int PINData=MachineConfig[fromLine][1];
    int PINClock=MachineConfig[fromLine][2];
      
    pinMode (PINCommLatch, OUTPUT);
    pinMode (PINData, OUTPUT);  
    pinMode (PINClock, OUTPUT);
    
  // Signal to the 595s to listen for data
  digitalWrite (PINCommLatch, LOW);
  
  for (byte reg = registerCount; reg > 0; reg--)
  {
    byte value = pValueArray [reg-1];

    for (byte bitMask = 128; bitMask > 0; bitMask >>= 1)
    {
      digitalWrite (PINClock, LOW);
    
      digitalWrite (PINData, value & bitMask ? HIGH : LOW);
        
      digitalWrite (PINClock, HIGH);
    }
  }
  // Signal to the 595s that I'm done sending
  digitalWrite (PINCommLatch, HIGH);
}  // sendSerialData


// Simple function to send serial data to one or more shift registers by iterating backwards through an array.
// Although g_registers exists, they may not all be being used, hence the input parameter.
void sendSerialData (
  byte registerCount,  // How many shift registers?
  byte *pValueArray, // Array of bytes with LSByte in array [0]
  int  fromLine)   
{
  int PINCommLatch=MachineConfig[fromLine][0];
  int PINData=MachineConfig[fromLine][1];
  int PINClock=MachineConfig[fromLine][2];
  
  // Signal to the 595s to listen for data
  digitalWrite (PINCommLatch, LOW);
  
  for (byte reg = registerCount; reg > 0; reg--)
  {
    byte value = pValueArray [reg - 1];

    for (byte bitMask = 128; bitMask > 0; bitMask >>= 1)
    {
      digitalWrite (PINClock, LOW);
    
      digitalWrite (PINData, value & bitMask ? HIGH : LOW);
        
      digitalWrite (PINClock, HIGH);
    }
  }
  // Signal to the 595s that I'm done sending
  digitalWrite (PINCommLatch, HIGH);
}  // sendSerialData


void loop()
{  
  
   if (digitalRead(switchPin0))// START BUTTON LINE 1
  {
   detect(0);
   
  }
   if (digitalRead(switchPin1))// START BUTTON LINE 2
  {
   detect(1);
  }
   if (digitalRead(switchPin2))// START BUTTON LINE 3
  {
   detect(2);
  }
    
}

void detect(int line) 
{
  if (line == 0)
  {
    int state0 = digitalRead(IRdetectPin0);
     if (laststate0 == HIGH && state0 == LOW) // only count on a LOW-> HIGH transition
  {
     increment (0);
     Serial.println(no1);
  }
  laststate0 = state0;// remember last state
  }
  
  if (line == 1)
  {
    int state1 = digitalRead(IRdetectPin1);
    if (laststate1 == HIGH && state1 == LOW) // only count on a LOW-> HIGH transition
  {
     increment (1);
     Serial.println(no2);
  }   
    laststate1 = state1;  // remember last state
  }
  
  if (line == 2)
  {
    int state2 = digitalRead(IRdetectPin2);
  if (laststate2 == LOW && state2 == HIGH) // only count on a LOW-> HIGH transition
  {
     increment (2);
     Serial.println(no2);  
  }
     laststate2 = state2;  // remember last state
  }
}
  
 
/*void blinks() 
{
  // Handling the blink of one LED.
  if ( (millis () - redLED0timer) >= redLED0interval)
     {
     digitalWrite (redLED0, HIGH);
     digitalWrite (redLED0, LOW);
     increment (0);
     redLED0timer = millis ();
     }
   
   if ( (millis () - redLED1timer) >= redLED1interval)
     {
     digitalWrite (redLED1, HIGH);
     digitalWrite (redLED1, LOW);
     increment (1);
     redLED1timer = millis ();
     }
     
   if ( (millis () - redLED2timer) >= redLED2interval)
     {
     digitalWrite (redLED2, HIGH);
     digitalWrite (redLED2, LOW);
     increment (2);
     redLED2timer = millis ();
     }
    
}*/
 /* int line1 = random (1,3);
  int line2 = random (1,4);
  int line3 = random (1,6);
    
  int k=0;
  if(line1==1)
  {
      digitalWrite(2, HIGH);   // set the LED on
      delay(300);
      digitalWrite(2, LOW);  
      increment(0);    
  }
  
  if(line2==1)
  {
      digitalWrite(3, HIGH);   // set the LED on
      delay(300);
      digitalWrite(3, LOW);  
      increment(1);    
  }
    
  if(line3==1)
  {
      digitalWrite(4, HIGH);   // set the LED on
      delay (200);
      digitalWrite(4, LOW); 
      increment(2);    
  }   
}*/

void increment(int line)
{
  if(line==0)
  {
   g_numberToDisplay = no1;
   no1++;
   show(g_numberToDisplay,line);
  }else if(line==1)
  {
   g_numberToDisplay = no2;
   no2++;
   show(g_numberToDisplay,line);
  }
  else if(line==2)
  {
  g_numberToDisplay = no3;
  
  no3++; 
  show(g_numberToDisplay,line);
  }
}
   
void show(int numberToDisplay,int fromLine)
{
  if (numberToDisplay < 10)
  {
    g_registerArray [3] = g_digits [0];
    g_registerArray [2] = g_digits [0];
    g_registerArray [1] = g_digits [0];
    g_registerArray [0] = g_digits [numberToDisplay];
  }
  else if (numberToDisplay < 100)
  {
...
}

Then If I do not understand how Arduino responds to a Firmata-formatted request to read a digital pin or set a PWM value or read an analog pin, how I could know at which part I must insert my code?

I am sorry for this very long and unconvenience question that might disturb you.

Then If I do not understand how Arduino responds to a Firmata-formatted request to read a digital pin or set a PWM value or read an analog pin, how I could know at which part I must insert my code?

Do you understand, at the hardware level, what analogRead() is doing? Probably not. Does that prevent you from calling analogRead()? Absolutely not.

Do you understand exactly what Servo.write() is doing? Probably not. Does that prevent you from controlling a servo? Absolutely not.

Do you need to understand exactly how the Arduino, running a Firmata sketch, responds to a Firmata-formatted request to read a digital pin in order to call the Firmata function that formulates the request to read a digital pin? Of course not. You need only understand what APIs the Firmata library provides to your development platform, and have a general understanding of what those APIs are trying to accomplish. For example, if the development platform provides a digitalRead() method, you can be reasonably confident that that is not the method to move a servo, and that it is the method to read a digital pin. Exactly how that API formats the request that it sends, via the serial port, to the Arduino, and exactly how the Arduino parses the request, and exactly how the Arduino responds to the request, and exactly how the Arduino generates a response, and exactly how the Firmata library parses the response are not really things that you need to understand in order to be able to read the state of a switch connected to pin 8.

I am sorry for this very long and unconvenience question that might disturb you.

There is no need to apologize for asking questions. The answers to your questions, for the Arduino side, are in the Firmata sketch. How the API formats its request is not, but that can be obtained, if necessary, by visiting the Firmata web site - http://firmata.org/wiki/Main_Page.

I just don't think that understanding exactly how the Firmata sketch accomplishes a digitalRead() is necessary in order to alter a GUI that runs on another computer.

I just don't think that understanding exactly how the Firmata sketch accomplishes a digitalRead() is necessary in order to alter a GUI that runs on another computer.

Yes sure I agree with you, surely no necessary to understand exactly how the Firmata sketch accomplishes a digitalReadl() in order to alter a GUI...So what you mean, I should do try and error?

If you look at the code, I can not put it here coz it is too long, The sketch doesn't even declare TOTAL_PINS, but it runs well, what happen? Then can it mean that it is valid for arduino mega and uno which has different amount of pins?

The sketch doesn't even declare TOTAL_PINS, but it runs well, what happen?

Sure it does. It includes Firmata.h which includes Boards.h which defines a number of platform-specific values (based on the board type).

So what you mean, I should do try and error?

I guess. I don't even know what changes you want to make to what GUI.

PaulS:

The sketch doesn't even declare TOTAL_PINS, but it runs well, what happen?

Sure it does. It includes Firmata.h which includes Boards.h which defines a number of platform-specific values (based on the board type).

So the Firmata sketch has been designed not only UNO, but also MEGA? Then no need anymore to modify it if I change my device to MEGA? So I only need to change the GUI code?

You can download so you might know the GUI appereance. I also would like to add database that will record all the data for certain period of time. This is really hard work.

I really hope the designer reply me soon,hmmm...

Then no need anymore to modify it if I change my device to MEGA?

Maybe. Maybe not. It depends on exactly what you want the Arduino to be able to do.

So I only need to change the GUI code?

Maybe. Maybe not. It depends on exactly what you want the GUI to be able to do.

You can download so you might know the GUI appereance.

Yes, I could.

I also would like to add database that will record all the data for certain period of time.

So, do that.

This is really hard work.

Oh. Well, that will limit what you can accomplish.

I really hope the designer reply me soon,hmmm...

Still trying to get someone else to do the work, huh?

LOL, you are so funny. I just try to open my mind... :stuck_out_tongue_closed_eyes: Yap if there is volunteer to help, very gracious. Yap from your answer it seems I must do really work hard.

Vielen Dank.

Hmm, could you explain explicitly what you mean with dumb device?

I mean that with the Firmata sketch uploaded, the functionality of the Arduino is fixed. It is limited by what the program on the other end tells it to do (read a digital pin, write to a digital pin, read an analog pin, etc.).

It can not also, for instance, run a web server or do timer related things or respond to external interrupts.

what do you mean that the arduino can not do timer related things? I really need to use interrupt, any idea to use interrupt in Firmata Sketch? why is it so?

I don't understand why you think you need Firmata. You already have a sketch that works, according to reply #4. Why do you want to ditch that and replace it with dumb code?

dxw00d: I don't understand why you think you need Firmata. You already have a sketch that works, according to reply #4. Why do you want to ditch that and replace it with dumb code?

I need Firmata so I can control my Arduino directly from PC, not just manual button pressing. I need to insert Firmata inside my sketch in order to communicate from Arduino to PC and vice versa.

I need Firmata so I can control my Arduino directly from PC, not just manual button pressing.

No, you don't. No-one ever needs Firmata. If you explain what you are sending from your PC, and what you want the Arduino to do with what it gets sent, we can probably help you modify your sketch.

I need to insert Firmata inside my sketch in order to communicate from Arduino to PC and vice versa.

You can't do that. You can run your sketch, or you can run Firmata. As has been explained, Firmata turns your Arduino into a dumb slave device.

Really dumb slave?

It means I must command something to make it works? And it can not run the code I insert in it (driving 4digits 7 segments each time the something pass by the IR sensor) ?

The reason I use Firmata because it is GUI so common people no need to type any code to operate the Arduino. Do you have any better idea?

Thank you for your willing to help.

Really dumb slave?

Yes, really dumb slave.

It means I must command something to make it works?

Yes, the Firmata sketch does nothing but wait for an instruction, and act on it.

Explain what you actually want to do.

What do you want your users to be able to do?

What should the Arduino do in response?

Hmmm, if Firmata sketch waiting for user instruction, then If I insert my code (to drive 4 digits 7 segments by detecting things pass by the sensor, timer using millis) then it should not slave anymore, am I right?

So here I explain what I do: Now I have been able to drive 4 digits 7 segments as counter (using IR sensor) and timer (using millis), I have build the hardware also the code, it has start/pause button, it works well..

But now I would like to control it not only using manual button, but control it by using PC, that's why I look for GUI. I decide not to create the GUI since I have no experience on that. Then I find Firmata GUI, then I try to upload StandarFirmata sketch and it works well ( I test with pin 13), then I think I see hope to control everything on my Arduino and also get the variable on the Arduino to put it in my database.

I hope this is clear.

Vielen Dank!

Ok. If I understand correctly, you want to put a start/pause button on the PC screen, so that the user can pause the processing. Is that correct?

The sketch you posted (reply #4) contains serial output. What is receiving that output?

Yes, you are right I want to put start/pause button on the PC Screen, and also we need to match the COM and serial baud. And after that I want the PC show the data from the variable looping inside the arduino.

Oh just dont care about that serial output, I don't need that, just put it there, I will just erase it. It just shows the amount of "no1" variable has been counting up