:::info # PHYS 3360 Chapter 11 Experiments > [name=Nikolai Nekrutenko - Wed/Fri Lab Group] ::: Online version of this article (I highly recommend this one over the PDF) - https://hackmd.io/@nekrutnikolai/SkNVCbHvi ## Experiment 11.1 In this experiment, a test program was run to ensure that the Arduino IDE is properly configured and connected. The built-in LED was programmed to blink for a certain duration. Here is an image of the LED in action: ![](https://i.imgur.com/BmZoGUj.jpg) The LED was verified to blink with an interval of 1s with the code below: ```C++ void setup() { // initialize digital pin LED_BUILTIN as an output. pinMode(LED_BUILTIN, OUTPUT); } // the loop function runs over and over again forever void loop() { digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second } ``` Here is the modified code to have the LED turn on for 0.1s, and off for 1s: ```C++ void setup() { // initialize digital pin LED_BUILTIN as an output. pinMode(LED_BUILTIN, OUTPUT); } // the loop function runs over and over again forever void loop() { digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) delay(100); // wait for 100ms digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second } ``` Here is the modified code to have the LED on for 5s, and off for 0.1s, so that I could capture it. ```C++ void setup() { // initialize digital pin LED_BUILTIN as an output. pinMode(LED_BUILTIN, OUTPUT); } // the loop function runs over and over again forever void loop() { digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) delay(5000); // wait for 5s digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW delay(100); // wait for 100ms } ``` ## Experiment 11.2 In this experiment, the Arduino read the input values of the logic switches in terms of binary and hexadecimal on the Digi-Designer as shown in the schematic shown below: ![](https://i.imgur.com/p1e4EgT.jpg) The following code was compiled and uploaded to the Arduino: ```C++ // I/O pins to read: const int NP=4; const int PINS[]={45, 47, 49, 51}; void setup() { // put your setup code here, to run once: // init serial comm as fast as possible Serial.begin(2000000); // set all pins to input for(int i=0; i<NP; i++){ pinMode(PINS[i], INPUT); } } void loop() { // put your main code here, to run repeatedly: // read I/O bits and pack that info into a byte int bval=0; for(int i=0; i<NP; i++){ if(HIGH == digitalRead(PINS[i])){ bitSet(bval, i); } } // print all the info to serial Serial.print(bval, HEX); Serial.print(" "); Serial.println(bval, BIN); delay(1000); } ``` A table was created from the values of the Serial Output of the Arduino: | SW 0 | SW 1 | SW 2 | SW 3 | Hex | Bin | | ---- | ---- | ---- | ---- | --- | ---- | | 0 | 0 | 0 | 0 | 0 | 0000 | | 1 | 0 | 0 | 0 | 1 | 0001 | | 0 | 1 | 0 | 0 | 2 | 0010 | | 1 | 1 | 0 | 0 | 3 | 0011 | | 0 | 0 | 1 | 0 | 4 | 0100 | | 1 | 0 | 1 | 0 | 5 | 0101 | | 0 | 1 | 1 | 0 | 6 | 0110 | | 1 | 1 | 1 | 0 | 7 | 0111 | | 0 | 0 | 0 | 1 | 8 | 1000 | | 1 | 0 | 0 | 1 | 9 | 1001 | | 0 | 1 | 0 | 1 | A | 1010 | | 1 | 1 | 0 | 1 | B | 1011 | | 0 | 0 | 1 | 1 | C | 1100 | | 1 | 0 | 1 | 1 | D | 1101 | | 0 | 1 | 1 | 1 | E | 1110 | | 1 | 1 | 1 | 1 | F | 1111 | The values do indeed correctly correspond to the switch positions. ## Experiment 11.3 A 7-segment LED display was wired to an Arduino through a set of resistors and the 74HC240 octal tri-state buffer IC to illuminate different segments and characters on the LED display. Here is a schematic of the experimental setup: ![](https://i.imgur.com/O66WILy.jpg) The code below, which was initially given in the assignment illuminates the segments of the display in the order a, b, c, d, e, f, g, and then all of them at once according to the segment assignments as in the schematic shown above. ```C++ const int NP=7; const int PINS[NP]={25, 27, 29, 31, 33, 35, 37}; void setup() { // put your setup code here, to run once: Serial.begin(2000000); for(int i=0; i<NP; i++){ pinMode(PINS[i], OUTPUT); } } void loop() { // put your main code here, to run repeatedly: int i, j, led[16] = {0, 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x7F, 1, 2, 4, 8, 0x10, 0x20, 0x40}; for(j=0; j<16; j++){ Serial.println(led[j], HEX); for(i=0; i<NP; i++){ digitalWrite(PINS[i], bitRead(led[j], i)); } delay(500); } Serial.println("done"); delay(2000); } ``` The Hexadecimal representations of the characters were derived in the image shown below: ![](https://i.imgur.com/bWE5DXD.png) Here is a modified version of program to display the characters 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, b, c, d, E, F: ```C++ const int NP=7; const int PINS[NP]={25, 27, 29, 31, 33, 35, 37}; void setup() { // put your setup code here, to run once: Serial.begin(2000000); for(int i=0; i<NP; i++){ pinMode(PINS[i], OUTPUT); } } void loop() { // put your main code here, to run repeatedly: int i, j, led[16] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x77, 0x7C, 0x58, 0x5E, 0x79, 0x71}; for(j=0; j<16; j++){ Serial.println(led[j], HEX); for(i=0; i<NP; i++){ digitalWrite(PINS[i], bitRead(led[j], i)); } delay(1000); } Serial.println("done"); delay(100); } ``` ## Experiment 11.4 A DHT 11 temperature and humidity sensor was hooked up to the Arduino and its response to external stimuli was examined. The code to gather the sensor's data is shown below: ```C++ #include <DHT.h> #include <DHT_U.h> #define DHTPIN 49 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); // declaring the sensor void setup() { // put your setup code here, to run once: Serial.begin(2000000); dht.begin(); } void loop() { // put your main code here, to run repeatedly: float temperature; float humidity; delay(2000); temperature = dht.readTemperature(); humidity = dht.readHumidity(); Serial.print("T = "); Serial.print(temperature, 1); Serial.print("°C, H = "); Serial.print(humidity, 1); Serial.println("%"); } ``` The room was recorded to be at 25.1°C at a humidity of 26.0%. Breathing onto the sensor results in the following graph of data, where each integer on the x-axis is two seconds as this is the `delay(2000)` in the program. The blue line represents the humidity as a percentage. The green line represents the temperature in degrees Celsius. ![](https://i.imgur.com/u1Fl0z6.png) The table shown below represents the Arduino's serial output from breathing onto the sensor. There is an interval of 2 secs between each: ![](https://i.imgur.com/BVJm8TD.png) ## Experiment 11.5 The Arduino's I/O speed was examined in this experiment by having it loop through setting the output of pin 25 high and then low with no delay as per the code below. The oscilloscope probe was hooked up to pin 25: ```C++ const int PIN=25; void setup() { // put your setup code here, to run once: pinMode(PIN, OUTPUT); } void loop() { // put your main code here, to run repeatedly: digitalWrite(PIN, HIGH); digitalWrite(PIN, LOW); } ``` This resulted in a waveform with a frequency of 134.7kHz. The period of this waveform is 7.42μs. The `HIGH` occured for 3.54μs, and the `LOW` occured for 3.88μs. The I/O speed, or average of these two values, is 3.71μs. Given that the Arduino has a clock speed of 16MHz, so a period of 62.5ns, it does make sense for the I/O speed to be longer than the clock speed. An image of the waveform at pin 25 is attached below: ![](https://i.imgur.com/cye26U4.jpg) ## Optional Experiment 11.5 The experiment above was continued with varying counts of signals to turn the outputs `HIGH` and `LOW`. In the code shown below, there were three commands to write the pin 25 to `HIGH` for every one command to turn the pin `LOW`. ```C++ const int PIN=25; void setup() { // put your setup code here, to run once: pinMode(PIN, OUTPUT); } void loop() { // put your main code here, to run repeatedly: The oscilloscope probe was attached to pin 25. igitalWrite(PIN, HIGH); digitalWrite(PIN, HIGH); digitalWrite(PIN, HIGH); digitalWrite(PIN, LOW); } ``` This resulted in a frequency of 67.9kHz, so a period of 14.72μs, which is close to double the period of the case with one `HIGH` and `LOW` write function, which was 7.42μs. This makes sense as there is four `digitalWrite` commands as opposed to two. The duration of the `HIGH` pulse was measured to be 10.73μs, while the `LOW` pulse duration was 3.99μs. This is consitent with the fact that there are three `HIGH` for every `LOW`. The waveform of the signal at pin 25 is shown below: ![](https://i.imgur.com/8m4QphI.jpg) Now, for the code shown below, there is one command to write the pin 25 to `HIGH` for every three commands to turn the pin `LOW`. ```C++ const int PIN=25; void setup() { // put your setup code here, to run once: pinMode(PIN, OUTPUT); } void loop() { // put your main code here, to run repeatedly: digitalWrite(PIN, HIGH); digitalWrite(PIN, LOW); digitalWrite(PIN, LOW); digitalWrite(PIN, LOW); } ``` This results in a frequency of 69.1kHz, so a period of 14.47μs which is relatively consistent with the previous code, which had a period of 14.72μs, as there are still four `digitalWrite` calls. The `HIGH` period was measured to be 3.62μs, while the `LOW` period was 10.85μs. This is consitent with the fact that there is a single `HIGH` for every three `LOW`. A graph of the waveform at pin 25 is shown below: ![](https://i.imgur.com/ghWsdM9.jpg) For the code shown below, there are three commands to write the pin 25 to `HIGH` for every three commands to turn the pin `LOW`. ```C++ void loop() { const int PIN=25; void setup() { // put your setup code here, to run once: pinMode(PIN, OUTPUT); } void loop() { // put your main code here, to run repeatedly: digitalWrite(PIN, HIGH); digitalWrite(PIN, HIGH); digitalWrite(PIN, HIGH); digitalWrite(PIN, LOW); digitalWrite(PIN, LOW); digitalWrite(PIN, LOW); } ``` The program above results in a frequency of 45.9kHz, so a period of 21.79μs which is approximately triple the period for the case of two `digitalRead`, 7.42μs. This makes sense as there are six `digitalRead` in this program. The `HIGH` period was measured to be 10.75μs, and the `LOW` was 11.03μs. This is consitent with the fact that there is a single `LOW` for every three `HIGH`. A graph of the waveform at pin 25 is shown below: ![](https://i.imgur.com/SRZ3jqg.jpg) ## Experiment 11.6 A debounce button on the Digi-Designer was connected to Arduino's pin 51. The code below reads the time when the button was pressed since the first press for each consecutive press and outputs the result into the Serial Monitor. ```C++ const int PIN=51; void setup() { // put your setup code here, to run once: Serial.begin(2000000); pinMode(PIN, INPUT); } void loop() { // put your main code here, to run repeatedly: double time; while(LOW == digitalRead(PIN)){}; // do nothing while low time = millis(); // get runtime in millisecs Serial.println(time/1000.0); while(HIGH == digitalRead(PIN)){}; } ``` Then, the program was modified to read the duration of the button press: ```C++ const int PIN=51; void setup() { // put your setup code here, to run once: Serial.begin(2000000); pinMode(PIN, INPUT); } void loop() { // put your main code here, to run repeatedly: double time_before, time_after; // get runtime in millisecs while(LOW == digitalRead(PIN)){}; // do nothing while low time_before = millis(); // modified to display 3 digits after the second, which is ms while(HIGH == digitalRead(PIN)){}; time_after = millis(); Serial.println((time_after-time_before)/1000, 3); } ``` ## Optional Experiment 11.6 A capacitance meter was built from a 555 timer in a one-shot configuration, based on *Experiment 10.1*, with a Digi-Designer debounce switch as the trigger and an Arduino to measure the time interval as in the schematic shown below: ![](https://i.imgur.com/uUkXrWp.png) This meter calculates the values based on the time of the signal from the timer and the fixed value of the resistance. The code was based on finding the duration of the pulse. There is a factor of ln(3) because the capacitor charges from 0 to 2/3Vcc. Here is the formula the Arduino uses to calculate the capacitance. $$T = ln(3)RC$$ $$C = \frac{T}{ln(3)R}$$ $$C = \frac{T}{ln(3)*107.9kΩ}$$ So if we want in microFarads, then R has to be on the order of 10^5. The code belerimentow finds the capacitance based on the 555 timer signal: ```C++ const int PIN=51; void setup() { // put your setup code here, to run once: Serial.begin(2000000); pinMode(PIN, INPUT); } void loop() { // put your main code here, to ru![](https://i.imgur.com/n7ULEep.png) me_after, time_diff, capacitance; // get runtime in millisecs while(LOW == digitalRead(PIN)){}; // do nothing while low apacitancee_before = millis(); // modified to display with a known resistor value of 107.9kOhms. digits after the second, which is ms while(HIGH == digitalRead(PIN)){}; time_after = millis(); // capacitance in microfarads time_diff = (time_after-time_before)/1000; capacitance = (time_diff/(107.9*1000))/log(3); Serial.print("Capacitance = "); Serial.print(capacitance*1000000, 2); Serial.println("µF"); } ``` Here is a table of the capacitors, measured values with the Arduino, and measured values with the multimeter: | Capacitor (µF) | Arduino (µF) | Multimeter (µF) | | -------------- | ------------ | --------------- | | 0.68 | 0.70 | 0.67 | | 1.00 | 1.03 | 0.96 | | 100 | 111.55 | 86.0 | | 220 | 211.36 | 182.1 | As can be seen from the table above, the values are quite close to each other. Any differences may be due to the non-linearity of certain components, or even inaccuracies of the multimeter.