Arnoldo B. Canales

C# program --- Mega 2560. Using debugging LEDs.

In this new iteration of the Arduino Mega 2560 program, the C# routine stays the same, but on the Arudion side, I am introducing four LEDs (Light-Emmiting Diods) with the purpose, aside from the light show, of having a way to debug code, to know what part of the program is being processed by observing what LED if being turned on and off. My intention is to eventually use another board to troubleshoot the main board, kind of a debugging board that keeps tabs of the main board.

The table below explains the purpose of each LED and its position in the program.

Table 1: LEDs purpose and position

LED # Name Memory variable LED color Comments
1 Start of Loop xStartOfLoop Green Blinks indicating start of main loop.
2 Reads Comm Port xReadCommPort Blue Blinks when reading Comm Port.
3 Print to Comm Port xPrintCommPort Red Blinks when sending info back to main computer.
4 End Of Loop xEndOfLoop Yellow Blinks when the end of loop is reached.

I am using a boolean variable switching its value by applying a Logical Negation Operator (!) and by doing so I am also switching the LED on and off, so as the LED turns On and Off, I now know where the program is at any given time. This helps a lot when complex programs are not doing what they are supposed to be doing and, in this case, by not switching a LED on/off the programmer knows what part of the code is not being processed.

The issue here is that I am loading, then running the code, on a separate board as supposed to run the programm in a sophistcated tool as Microsoft Visual Studio that tells you exactly where a program is failing and the reason of the failure and so many other features modern debuggers have, so I have to get creative and come up with ways to debug code under Arduino likle turning LEDs on and off to indicate where the code is at any given time.

So by turning the red LED on and off I am signaling that the program just "passed by" that specific part of the code. In the case of the red LED, when on/off, indicates sending information to the main computer using the statement "Serial.print("xxx command");"


//------------------------------------------------------------------------
//  Basic Communication Framework.
//  Routine to communicate with the Arduino Mega 2560 Controller.
//  Uses three leds to help debug the program.
//  June 26, 2018.
//------------------------------------------------------------------------
#include <stdio.h>
//
//Memory variables
//
//Assigning Name to Controller Board
String xCntrlrName = "A1";
//
//Buzzer plugged at Controller's pin 13.
const int xBuzzerPin = 13;
//
//Variables to talk to the Master Computer via USB port
byte cmdByte0;
byte cmdByte1;
byte cmdByte2;
byte cmdByte3;
//
bool xStartOfLoop = true;
bool xReadCommPort = false;
bool xPrintCommPort = false;
bool xEndOfLoop = false;
//
//Declaration of pins to be used
const int LedPin31 = 31;         //Start of Loop.
const int LedPin32 = 32;         //Reading Communications Port.
const int LedPin33 = 33;         //Printing To Communications Port.
const int LedPin34 = 34;         //End of Loop and cycling back to start of loop.
//
//------------------------------------------------------------------------
// Routine: setup() - 
// Main Setup.
//------------------------------------------------------------------------
void setup() 
{
  pinMode(LedPin31,OUTPUT);     //Start of Loop.
  pinMode(LedPin32,OUTPUT);     //Reading Communications Port.
  pinMode(LedPin33,OUTPUT);     //Printing To Communications Port.
  pinMode(LedPin34,OUTPUT);     //End of Loop and cycling back to start of loop.
  digitalWrite(LedPin31,HIGH);  //GREEN
  digitalWrite(LedPin32,LOW);   //BLUE
  digitalWrite(LedPin33,LOW);   //RED
  digitalWrite(LedPin34,LOW);   //YELLOW
  //
  pinMode(xBuzzerPin,OUTPUT); //initialize the buzzer pin as an output
  //
  // Activate serial monitor to send/receive communications using 9600 bauds
  Serial.begin(9600);
}
//
//------------------------------------------------------------------------
// Routine: loop() - 
// Main Loop.
//------------------------------------------------------------------------
void loop() 
{
  xStartOfLoop = !xStartOfLoop;
  digitalWrite(LedPin31,xStartOfLoop);  //GREEN LED on/off
  //
  //
  //
  if (Serial.available() > 2) //Read data to bytes
  {
    xReadCommPort = !xReadCommPort;
    digitalWrite(LedPin32,xReadCommPort); //BLUE LED on/off
    //
    cmdByte0 = Serial.read();    delay(10); 
    cmdByte1 = Serial.read();    delay(10); 
    cmdByte2 = Serial.read();    delay(10); 
    cmdByte3 = Serial.read();    delay(10); 
  }
  //
  //  
  //
  // 
  if(cmdByte0 == 1)          // First byte is equal to "1", then someone maybe talking to Arduino,
  { 
    if(cmdByte1 == 1)        // Second byte is equal to "1".
    { 
      if(cmdByte2 == 1)      // Third byte is equal to "1".
      {
        if(cmdByte3 == 1)    // Forth byte is equal to "1", tell me your ID!
        {
          Serial.print(xCntrlrName);
        }
      }   
    }
    //
    //..
    if(cmdByte1 == 2) {    }
    if(cmdByte1 == 3) {    }
    //..
    //
    if(cmdByte1 == 4)       // Second byte is equal to "4".
    {    
      if(cmdByte2 == 7)     // Third byte is equal to "7".
      {
          buzzerX(10);
          Serial.print("1st command");
          xPrintCommPort = !xPrintCommPort;
      }
      if(cmdByte2 == 8)     // Third byte is equal to "8".
      {
          buzzerX(10);
          Serial.print("2nd. command");
          xPrintCommPort = !xPrintCommPort;
      }
      if(cmdByte2 == 9)     // Third byte is equal to "9".
      {
          buzzerX(10);
          Serial.print("3rd. command.");
          xPrintCommPort = !xPrintCommPort;
      }
      digitalWrite(LedPin33,xPrintCommPort); //RED LED on/off
    }
  }
  //
  //
  //Reset bytes to zero.
  cmdByte0 = 0;
  cmdByte1 = 0;
  cmdByte2 = 0;
  cmdByte3 = 0;
  //
  //
  //
  xEndOfLoop = !xEndOfLoop;
  digitalWrite(LedPin34,xEndOfLoop);  //YELLOW LED on/off
  //
  delay(50);  //This delay is introduced with the solo purpose of this example 
              //and has no practical use on this program. 
}
//
//-------------------------------------------------------------------------------
// buzzerX Routine
//-------------------------------------------------------------------------------
void buzzerX(int xDuration)
{
  for(int i=0; i < xDuration; i++)
  {
     digitalWrite(xBuzzerPin,HIGH);
     delay(5);//wait for 5ms
     digitalWrite(xBuzzerPin,LOW);
     delay(5);//wait for 5ms
  }
}

  					


using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;

namespace CS_Comm
{
    public partial class Form1 : Form
    {
        public string xCntrllerName1 = "A1";
        public string PCPort1;
        static SerialPort ControllerPort;
        DataTable xDataStream;
        //
        public Form1(){InitializeComponent();}
        //
        //----------------------------------------------------------------------
        //
        //Load Form - Form1_Load
        //
        //----------------------------------------------------------------------
        private void Form1_Load(object sender, EventArgs e)
        {
            if (HandShake(9600, xCntrllerName1, 1, 1, 1, 1))
            {
                lblControllerName1.Text = xCntrllerName1 + " @ " + PCPort1;
                lblMessages.Text = "Connection Successful - Connected via " + PCPort1 + " to board " + xCntrllerName1 + ".";
                btnCommand1.Enabled = true;
                btnCommand2.Enabled = true;
                btnCommand3.Enabled = true;
            }
            else
            {
                lblMessages.Text = "Error with connection....";
            }
            //
            xDataStream = CreateTable0();
            dataGridView0.DataSource = xDataStream;
            Format_dgv0(dataGridView0);
        }
        //
        //----------------------------------------------------------------------
        //
        // DataGrid connected to a DataTable - Create Table0 for Data Stream DataGridView
        //
        //----------------------------------------------------------------------
        //
        public DataTable CreateTable0()
        {
            DataTable xTable = new DataTable();
            xTable.Columns.Add("ReturnInfo", typeof(byte));
            return xTable;
        }
        //
        //----------------------------------------------------------------------
        //
        //Format DatagridView0 - This DataGridView stores the Data Stream
        //
        //----------------------------------------------------------------------
        //
        public void Format_dgv0(DataGridView pdgv)
        {
            //dataGridView Formatting
            dataGridView0.Columns[0].Width = 90;
            dataGridView0.Columns[0].HeaderText = "Data returned";
            //
            dataGridView0.ColumnHeadersDefaultCellStyle.BackColor = Color.LightBlue;
            foreach (DataGridViewColumn col in dataGridView0.Columns)
            {
                col.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
                col.SortMode = DataGridViewColumnSortMode.NotSortable;
                col.DefaultCellStyle.Font = new Font("Calibri", 8, FontStyle.Regular);
                col.DefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomCenter;
            }
        }
        //
        //----------------------------------------------------------------------
        //
        //Handshake with Controller - Identify Com Port and Establish connection.
        //
        //----------------------------------------------------------------------
        public Boolean HandShake(int bauds, string passCode, byte parameter1, byte parameter2, byte parameter3, byte parameter4)
        {
            try
            {
                byte[] parameters_buffer = new byte[4];
                parameters_buffer[0] = Convert.ToByte(parameter1);
                parameters_buffer[1] = Convert.ToByte(parameter2);
                parameters_buffer[2] = Convert.ToByte(parameter3);
                parameters_buffer[3] = Convert.ToByte(parameter4);
                //
                int intReturnValue = 0;
                byte byteReturnValue = 0;
                string returned_passCode = "";
                int parameters_Read = 0;
                //
                string[] ports = SerialPort.GetPortNames();
                foreach (string nextPort in ports)
                {
                    ControllerPort = new SerialPort(nextPort, bauds);
                    ControllerPort.Open();
                    ControllerPort.Write(parameters_buffer, 0, 4);
                    Thread.Sleep(200);
                    //
                    returned_passCode = "";
                    //
                    parameters_Read = ControllerPort.BytesToRead;
                    while (parameters_Read > 0)
                    {
                        byteReturnValue = (byte)ControllerPort.ReadByte();
                        intReturnValue = (int)byteReturnValue;
                        //
                        returned_passCode = returned_passCode + Convert.ToChar(intReturnValue);
                        parameters_Read--;
                    }
                    ControllerPort.Close();
                    //
                    PCPort1 = nextPort;
                    //
                    if (returned_passCode.Contains(passCode)) return true;
                }
                return false;
            }
            catch (Exception e){ MessageBox.Show("Error Message at HandShake: " + e); return false; }
        }
        //
        //----------------------------------------------------------------------
        //
        //Given an order to Controller and get an answer back 
        //
        //----------------------------------------------------------------------
        //
        public string comm_message(byte par_1, byte par_2, byte par_3, byte par_4)
        {
            try
            {
                byte[] parameters_buffer = new byte[4];
                parameters_buffer[0] = Convert.ToByte(par_1);
                parameters_buffer[1] = Convert.ToByte(par_2);
                parameters_buffer[2] = Convert.ToByte(par_3);
                parameters_buffer[3] = Convert.ToByte(par_4);
                //
                ControllerPort.Open();
                ControllerPort.Write(parameters_buffer, 0, 4);
                Thread.Sleep(200);
                //
                xDataStream.Clear();
                //
                int intReturnValue = 0;
                byte byteReturnValue = 0;
                char charReturnValue = (Char)intReturnValue;
                string returned_MessageAsIs = "";
                //
                int parameters_Read = ControllerPort.BytesToRead;
                txtNumOfChars.Text = parameters_Read.ToString();
                while (parameters_Read > 0)
                {
                    //Read data from Comm Port
                    byteReturnValue = (byte)ControllerPort.ReadByte();  //Read data from Comm Port
                    //Read data from Comm Port
                    //
                    intReturnValue = (int)byteReturnValue;
                    xDataStream.Rows.Add(byteReturnValue);
                    //
                    //if ((intReturnValue >= 48 && intReturnValue <= 57)  || 
                    //    (intReturnValue >= 65 && intReturnValue <= 90)  || 
                    //    (intReturnValue >= 97 && intReturnValue <= 122) || 
                    //    (intReturnValue == 32) || (intReturnValue == 46)) 
                    //{
                        //Save incoming message "as it comes in"
                        returned_MessageAsIs = returned_MessageAsIs + Convert.ToChar(intReturnValue);
                    //}
                    parameters_Read--;
                }
                ControllerPort.Close();
                //
                return returned_MessageAsIs;
            }
            catch (Exception e){ MessageBox.Show("Error Message at comm_message : " + e); return "Invalid Exception!"; }
        }
        //
        //----------------------------------------------------------------------
        //
        //Buttons
        //
        //----------------------------------------------------------------------
        //
        private void btnCommand1_Click(object sender, EventArgs e)
        {
            String Msg = comm_message(1, 4, 7, 0);
            txtCommand1.Text = Msg;
            txtCommand2.Text = "";
            txtCommand3.Text = "";
        }
        //
        private void btnCommand2_Click(object sender, EventArgs e)
        {
            String Msg = comm_message(1, 4, 8, 0);
            txtCommand1.Text = "";
            txtCommand2.Text = Msg;
            txtCommand3.Text = "";           
        }
        //
        private void btnCommand3_Click(object sender, EventArgs e)
        {
            String Msg = comm_message(1, 4, 9, 0);
            txtCommand1.Text = "";
            txtCommand2.Text = "";
            txtCommand3.Text = Msg;
        }
    }
}

  					

VIDEOS

 

Video: C# --- Mega 2560 interface.

 

Video: Controller Mega 2560 playing the buzzer