04—Embedded Programming

Asignment

Outline

00 — Thoughts on Learning and Programing

This week was challenging in terms of prioritization. I found myself wanting to go deeper with the coding and than going slightly too deep and getting lost. I tried to avoid using chat GPT as much as possible and to try and figure what was going on by reading the arduino official documentation. So that said it was very much a bootstrapping process for me. Programming has so many interlinked and dependant concepts that I feel like you just have to jump into the center of it and climb your way out. The trick was trying to pick things to work on that didn’t get me too lost.

01 — Group Asignment Reflection and Link

Reflection:

While I think it is incitful to learn how to get an MCU chip up and runnining from scratch the only context I think I would want to use this is hardware hacking. I know in the context of power tool batteries and scientific calculators I have come across projects that require reflashing chips. Ultimately though, since I plan to develop around small dev boards because I would never scale a personal electronics project into a full fledged product on my own I will be sticking with the XIAOs.

I do find the compiling times that the ESP32 boards take to be a bit annoying so when possible I might use the SAMD21 flavor of the XIAO. As far as programming goes once I am more comfortable with the basics of coding in arduino’s flavor of C++ I might look into circuit python mostly because I think knowing a little python could be useful.

Link to Group Project

02— Sifting through an example program

  1. Working through all functions in the program I copied from class. I simulated an arduino and ran the code code in TinkerCAD circuits.
    int numberExecutions = 0;
    
    void setup() // interesting there is a delay and print in the setup I guess you can put anything in setup as long as it only needs to run once
    {
      Serial.begin(115200); // sets baud rate or bit rate the console reads at
      pinMode
      Serial.println("Morning!"); // Message at initialization
      delay(1000); // delay before start program
    }
    
    void loop()
    {
      Serial.print("Hey "); // this print variation apears to just be for ASCII
      String name = "Andrew "; // stores an ASCII text label to the string
      delay(1000); // time callout here asumes ms
    
      Serial.println(name);// this refferences the string, 
      //serial println finishes the line whereas serial.print just puts the label on the current lin
      
      delay(1000);
    
      float temperature = 23.3; // this denotes temperature as a floating point number which is a non integer number that can be recorded to a high resolution
      int kelvins = temperature + 273; // int (integer) specifies the new variable kelvins to be displayed in whole numbers and = temperature + a value
    
      Serial.print("It's ");
      Serial.print(kelvins);
      Serial.println(" K degrees out there ;):");
    
    
      delay(500);
      float time = millis();
      Serial.print("Its been ");
      Serial.print(time / 1000);
      Serial.println(" seconds since bootup");
    
      //Number of executions is 4
    
      Serial.print("I've run ");
      Serial.print(numberExecutions);
      Serial.println(" times!");
    
    }
    

    Variables Used

    Var. typeVar. NameValue
    stringnameAndrew
    floattimemillis()
    intkelvinstemperature + 273
    floattemperature23.3
    intnumberExecutions0
  1. Kept on editing the above code until I fixed all of the errors from my initial hand typed copy from class. I worked line by line consulting the online Arduino code documentation when needed and Dani’s HackMD webpage. I added some explanatory comments as I went through by using // . Things like missing and ; were primary issues that were causing compilation issues. Could not remember how to fix numberExecutions counter and decided to focus on understanding and get comfortable writing the core syntax.

03 — Essential Arduino Concepts and Syntax

About Section: This is a section I just updated continually throughout the whole process detailed on this page.

04—Writing Code for the Barduino

  1. Adapting original code to control core capabilities of the barduino: LED, RGB light, buzzer.
    1. Getting it onto the Barduino → from class installing the board library into the arduino IDE.

      This link provides all of the steps needed to configure the board with Arduino IDE.

      • This happeded to me “!!! bug The first time you connect your board it may connect and disconnect, once you program it, it will show as connected.”
      • Program upload issue? Reset the board by putting it into boot mode! Reset Button + Boot button then release Boot Button. This will stop any code running into the ESP32S3 making it available for programming at any time. Once you upload the code it will not run automaticaly, please reset your board in normal mode again.

    1. I decided to add in the buzzer command to the original code. I just consulted some of the arduino code examples to figure out how to set the pin output. Also wanted to figure out how to give pin 46 a variable name. Figured this out through reading this example code . I now realize that the pin is declared outside of the void setup and it uses int which seems a little superulous because a pin would alway be an int. Similarly it is interesting it defualts to intrepreting the number callout as a pin. I am unclear what things should and should not be declared before void setup() .
      int buzzer_pin = 46;
      
      void setup()
      {
      pinMode(buzzer_pin,OUTPUT);
      }
      void loop()
      {
      tone(buzzer_pin,400,250);
      delay(2000);
      }
    1. Flashing external LED 48. Similiar code to buzzer. I wonder if I were to use a sensor the pinmode callout would be INPUT.
      int LED_BUILTIN_48 = 48;
      
      void setup() {
        pinMode(LED_BUILTIN, OUTPUT);
      }
      
      void loop() 
      {
       digitalWrite(48, HIGH);
       delay(1000);
       digitalWrite(48,LOW);
       delay(1000);
      }
    1. RGB pulse different colors. Looking at the example code provided on the Barduino page. It is clear that a library is needed so I went ahead and installed that by going into arduino IDE then searched the package name then install. I addded comments inline with the code to workthrough what was going on. I quickly looked at the function section in the library page, but decided not to introduce learning the functions of the library this weekend because I still dont fully understand the basics of the arduino language. In a general way from the original comments I see what they do.

      #include <Adafruit_NeoPixel.h>  // calling upon the library is done before setup function
      
      #define PIN 38  // do not know what define does
      
      #define NUMPIXELS 1  // this is how many pixels you have being one NUMPIXEL I asume is a variable
      
      // When setting up the NeoPixel library, we tell it how many pixels,
      // and which pin to use to send signals. Note that for older NeoPixel
      // strips you might need to change the third parameter -- see the
      // strandtest example for more information on possible values.
      Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
      
      void setup() {
        pixels.begin();  // INITIALIZE NeoPixel strip object (REQUIRED)
      }
      
      void loop() {
        pixels.setPixelColor(0, pixels.Color(0, 150, 0)); // dont understand what the first 0 does but I asume 0, 150, 0 are RGB.
        pixels.show();  // Send the updated pixel colors to the hardware. Not sure why this would not be part of the last function
        delay(500);  // Pause before next pass through loop
        pixels.setPixelColor(0, pixels.Color(150, 0, 0));
        pixels.show();  // Send the updated pixel colors to the hardware.
        delay(500);
        pixels.setPixelColor(0, pixels.Color(0, 0, 150));
        pixels.show();  // Send the updated pixel colors to the hardware.
        delay(500);
      }
    1. Print simple serial data into console when capacitive buttons are pressed.

      Barduino example code

      void setup() {
        Serial.begin(115200);
      }
      
      void loop() {
        int touch = touchRead(4);//its only printing for touch pad 4 it reads an integer value and its using a built in function 'touchRead' which is acting on pin 4 it is specifically built for the esp boards and in this case the touch sensor is capacitive
        Serial.println(touch); 
        delay(500);
      }

      Resulting errors after running code on Barduino

      I received a bunch of numbers as a response my asumption after looking at the touchRead implmentation on other websites from a simple google search I noticed that there was more interpretation of the input going on. So educated guess was it was just reading and printing the values that the capacitive touch sensors were reading.

      Chat GPT “touchRead fucntion in arduino” — yes it was mispelled. I decided to prompt chat GPT to generate the code this approach made a lot of sense to me … comments are mine.

      const int touchPin = 4;
      int threshold = 40000;  // Adjust based on your sensor's environment
      
      void setup()
      { 
      Serial.begin(115200);
      }
      
      void loop() {
        int touchValue = touchRead(4); // declaring the following as an integer value -> relating it to the built in function touch read and asigning touch read to the pin used on barduino for the touch input [4]
         Serial.println(touchValue);
        if (touchValue < threshold) { // threshold is declared earlier so I gues I will set this to a low positive reading.
          Serial.println("Touched!");
        }
        delay(100);
      }

      *Raw serial print data from previous code 22,700 (not touched) → >40,000 (when touched)

      *Chat GPT code suggested excluded void setup() weird… I learned this needs to always be included.

      *added in Serial.println(touchValue); to see if I could get anyhthing printed turns out chat gpt also excluded initializing serial communication in setup.

    1. Frankenstein’d touch button and neo pixel code to trigger neo pixel when touch04 is activated. I wanted to test if my intuition about selection tree(?) was correct so I coded the tree based on my notes and had no Idea if it was going to work.
      const int touch_1 = 4;
      int threshold = 40000;  // Adjust based on your sensor's environment
      
      #include <Adafruit_NeoPixel.h>  // calling upon the library is done before setup function
      #define PIN 38  // do not know what define does=
      #define NUMPIXELS 1  // this is how many pixels you have being one NUMPIXEL I asume is a variable
      Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
      
      void setup()
      {   Serial.begin(115200);
          pixels.begin();  // INITIALIZE NeoPixel strip object (REQUIRED)
      }
      
      void loop() {
        int touchValue = touchRead(4);
         // declaring the following as an integer value -> relating it the built in function touch read and asigning touch read to the pin used on barduino for the touch input [4]
        if (threshold < touchValue) { // threshold is declared earlier so I gues I will set this to a low positive reading.
          Serial.println("Touched!");
          pixels.setPixelColor(0, pixels.Color(0, 150, 0)); // dont understand what the first 0 does but I asume 0, 150, 0 are RGB.
          pixels.show(); }
        else
          {pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // dont understand what the first 0 does but I asume 0, 150, 0 are RGB.
          pixels.show(); }
      
        delay(100);
      }
      

g. Getting raw data and serial printing from temperature sensor. Looked at sample code from Barduino and added Temperature_LM75_Derived.h to my arduino IDE. Comments are my own. Could not get this to work and decided this would take a lot of sleuthing to figure out why and decided to put my time elsewhere.

#include <Temperature_LM75_Derived.h>
#include<Wire.h>

TI_TMP102 temperature; //declaring an object named temperature from the class TI_TMP102 I am not sure how this works or why it is necarry at all.

void setup() {
  Serial.begin(115200);
  Wire.begin(); // chat gpt says that it initializes the i2c communication using the wire library I don't think it needs to be included but I included it anyway
}

void loop() {
  Serial.print("Temperature = ");
  Serial.print(temperature.readTemperatureC()); // asumming readTemperatureC is a library functin and could probably be changed to readTemperatureF read one of the git files and yes this is correct
  Serial.println(" C");

  delay(500);
}

*not too familiar with working with I2C from looking at the repo page for Wire.h it doesnlt look I need to tell I2C where to look because it should default to read from the right pins.

*Looking at the Repo page for Temperature_LM75_Derived.h I got a sense for what functions it includes particularly conversions to other common temperature units as I suspected.

05— Basic Program of my own

  1. Generates a tone and a color for each capacitive button. This was another mix of code I had already written.
    #include <Adafruit_NeoPixel.h>  // calling upon the library is done before setup function
    #define PIN 38  // do not know what define does=
    #define NUMPIXELS 1  // this is how many pixels you have being one NUMPIXEL I asume is a variable
    Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
    
    const int buzzer = 46;
    const int tactile = 0;
    const int touch1 = 6;
    const int touch2 = 5;
    const int touch3 = 4;
    const int touch4 = 7;
    int threshold = 40000;  // Adjust based on your sensor's environment
    
    
    void setup()
    {   Serial.begin(115200);
        pixels.begin();  // INITIALIZE NeoPixel strip object (REQUIRED)
    }
    
    void loop() {
      int touchValue = touchRead(touch1);
      int touchValue2 = touchRead(touch2);
      int touchValue3 = touchRead(touch3);
      int touchValue4 = touchRead(touch4);
       
      if (threshold < touchValue) { 
        Serial.println("Touched 1! ");
        pixels.setPixelColor(0, pixels.Color(50, 0, 0)); 
        pixels.show(); 
         tone(buzzer, 200, 50); }
      
      else if (threshold < touchValue2) { 
        Serial.println("Touched 2! ");
        pixels.setPixelColor(0, pixels.Color(0, 50, 0)); 
        pixels.show(); 
         tone(buzzer, 250, 50); }
      else if (threshold < touchValue3) { 
        Serial.println("Touched 3! ");
        pixels.setPixelColor(0, pixels.Color(0, 0, 50)); 
        pixels.show(); 
         tone(buzzer, 300, 50); }
       else if (threshold < touchValue4) { 
        Serial.println("Touched 4! ");
        pixels.setPixelColor(0, pixels.Color(50, 10, 50)); 
        pixels.show(); 
         tone(buzzer, 350, 50); }
      else
        {pixels.setPixelColor(0, pixels.Color(0, 0, 0));
        pixels.show(); }
    
      delay(100);
    
    }

06— Switching over to Xiao Platform

  1. I am planning to use the Xiao C3 as my development platform moving forward so I am going to be working using this development board and examples from this Xiao tutorial series relevant to my Final Project. In the spirit of spiral development the goal is to increment a servo at a rate set by a potentiometer. So potentiometer will be broken up into 8 discrete steps than the program will pulse the servo for a set duration at the rate defined by the pot.
  1. To start lets try to read a pot. Code taken from here notes are my own. I don’t fully understand why it needs to use the approach detailed below to read the POT. The guide was not very clear on this.. ok I think I got it. The pot full rotation is 300 degrees not 360. The ADC refference voltage would be the pot max I think in this scenario.
    
    #define ROTARY_ANGLE_SENSOR A0
    #define ADC_REF 3 
    #define GROVE_VCC 3 
    #define FULL_ANGLE 300 
     
    void setup()
    {
        Serial.begin(9600);
        pinMode(ROTARY_ANGLE_SENSOR, INPUT); // setting rotary angle pin as input this variable is set to A0 in the define section above
    }
     
    void loop()
    {   
        float voltage;//strange that you are defining the variable type without an argument 
        int sensorValue = analogRead(ROTARY_ANGLE_SENSOR);//Read the analog value at the rotary potentiometer pin
        voltage = (float)sensorValue*ADC_REF/1023;//Calculate real-time voltage
        float degrees = (voltage*FULL_ANGLE)/GROVE_VCC;//Calculate the rotation angle of the knob
        Serial.println("The angle between the mark and the starting position:");//Print characters at the serial port
        Serial.println(degrees);//Print the rotation angle value of the rotary potentiometer at the serial port
        delay(100);
    }
  1. Decided to work with the original built in example from Arduino because it was eaiser for me to understand. Rewrote it and tested it in Tinker Circuits.
    void setup(){
      Serial.begin(9600);
      
    }
    
    void loop(){
    	int sensorValue = analogRead(A0);
    	float voltage = sensorValue * (5 / 1023.0);
    	Serial.println(voltage);
    	}

    *original code is for a standard arduino which has 10 bit DAC [1023] and a nominal V of 5V. The Xiao C3 is 3.3 V and has a 12 bit ADC [4095]. So basically the ADC can sample the Analog input at a resolution of 4095. Similarly I think I can increase the baud rate?

07— ESP32 C3 Data Sheet

Spent time goint through the ESP32 C3 datasheet because that is most likely what I will be programming on.

08— Outlining final Project Software/Hardware needs

Quick breakdown of full control program

Citations

Project Files

—All code is provided in text body