<jupyter_start><jupyter_text>Digital to Analog Converter - DAC     Keywords:  ```Digital to Analog Converter (DAC)```, ```Digital Signal Processing (DSP)```, ```Arduino```  I. Introduction     1. Background  Digital systems often need to produce an effect in the physical world, in the form of continuous time-varying quantities. Such goal can be accomplished using the finite discrete numerical representation capabilities of embedded systems, to generate analog physical quantities (e.g. a voltage). This session aims at experimenting this process in practice, using the Arduino as a basic function generator and oscilloscope.     Note         If you have difficulties with the hardware setup, use Tinkercad [1]. Files with pre-recorded data are also provided for some experiments.   2. Objectives* Understand the process of converting a digital signal to an analog representation* Learn how to use Arduino-type systems as a basic function generator and signal visualizer * Explore the use of bitwise operators for low-level numerical manipulation   3. Materials (optional) * Arduino IDE* 1x Breadboard* 5x Jumper wires* 10x 10kOhm resistors* 1x Arduino (or analogous device)* 1x USB cable  II. Experimental  Adapt the firmware developed in the  A013 session  to sample the analog inputs A0 and A1 at 50Hz, and stream them, together with the elapsed time since the board began running the program, through the serial port (the suggested baud rate is 115200bps). As before, a formatted sequence of comma-separated values (CSV) should be used (e.g. ,,); make sure that each sequence ends with a line feed character. Spreadsheet software of your choice was previously suggested to analyze the data, however, you can also acquire the data stream produced by the Arduino directly from a Python script. The following code can be used as a base (note that this is an optional step):<jupyter_code>!pip install serial >/dev/null 2>&1
import serial
import time

acqtime = 10

try:
    port = serial.Serial('<SERIAL PORT OF YOUR ARDUINO>',115200)
    port.flushInput()
    
    fp = open("data.txt", "w")
    
    print(port.name)
    
    t = time.time()
    while (time.time()-t) <= acqtime:
        data = port.readline()
        print(data.strip())
        fp.write(data)
except:
    print("error")
finally:
    fp.close()    
    port.close()
    print("stop")<jupyter_output><empty_output><jupyter_text>Warning!         The serial port can only be accessed by a single application at any given time, which means that, to acquire data in your Python script, the Arduino serial monitor needs to be closed (and vice versa). THIS FEATURE IS NOT AVAILABLE FOR THE EMULATOR.  III. Explore     1. Quizz  1) Modify your firmware so that, in addition to sampling and streaming the analog inputs, your Arduino works as a square waveform generator with [0; Vcc] amplitude, 50% duty cycle, and 1Hz frequency. You can sample the waveform by connecting the output pin to one of the analog inputs streamed by your firmware (e.g. A0).<jupyter_code># Example: 1 Hz

import pylab as pl
import matplotlib.pyplot as plt

fname = '../X.Example_Files/A014_data/L3.1-1Hz-115200bps.csv'

raw = pl.loadtxt(fname, delimiter = ',')

col_1 = raw[:, 0]
col_2 = raw[:, 1]

plt.title('Example - 1 Hz', {'size':14})

plt.xlabel('Time (ms)', color = "#00a0e4")
plt.ylabel('Vout (V)', color = "#00a0e4")

plt.plot(col_1, col_2, color = "#00a0e4")

plt.show()<jupyter_output><empty_output><jupyter_text>2) Modify your experimental setup so that the output waveform amplitude is [0; Vcc/2], and the frequency can be adjusted through a command sent via the serial port (e.g. F5 would produce a 5Hz square wave). Test your setup for different waveform frequencies (in particular 100Hz) and discuss your results.<jupyter_code># Example: 1 Hz

import pylab as pl
import matplotlib.pyplot as plt

fname = '../X.Example_Files/A014_data/L3.2-1Hz-115200bps.csv'

raw = pl.loadtxt(fname, delimiter = ',')

col_1 = raw[:, 0]
col_2 = raw[:, 1]

plt.title('Example - 1 Hz', {'size':14})

plt.xlabel('Time (ms)', color = "#00a0e4")
plt.ylabel('Vout (V)', color = "#00a0e4")

plt.plot(col_1, col_2, color = "#00a0e4")

plt.show()
# Example: 1 Hz

import pylab as pl
import matplotlib.pyplot as plt

fname = '../X.Example_Files/A014_data/L3.2-100Hz-115200bps.csv'

raw = pl.loadtxt(fname, delimiter = ',')

col_1 = raw[:, 0]
col_2 = raw[:, 1]

plt.title('Example - 100 Hz', {'size':14})

plt.xlabel('Time (ms)', color = "#00a0e4")
plt.ylabel('Vout (V)', color = "#00a0e4")

plt.plot(col_1, col_2, color = "#00a0e4")

plt.show()<jupyter_output><empty_output><jupyter_text>3) Devise a 3-bit circuit considering the R-2R resistor ladder network (in the following Figure), and characterize the expected behavior, namely the number of steps, step size, output voltages for each step, and other details that you may find relevant.        R-2R resistor ladder (image by Lsibilla ).|<jupyter_code># Example: 1 Hz

import pylab as pl
import matplotlib.pyplot as plt

fname = '../X.Example_Files/A014_data/L3.3.csv'

raw = pl.loadtxt(fname, delimiter = ',')

col_1 = raw[:, 0]
col_2 = raw[:, 1]

plt.title('Example', {'size':14})

plt.xlabel('Time (ms)', color = "#00a0e4")
plt.ylabel('Vout (V)', color = "#00a0e4")

plt.plot(col_1, col_2, color = "#00a0e4")

plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1083208395802099, 'fraction_numerical': 0.034857571214392806, 'mean_word_length': 4.294642857142857, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '308270', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1829, 'n_tokens_neox': 1671, 'n_words': 665, 'path': 'A.Signal_Acquisition/A014 Digital to Analog Converter.ipynb', 'repo_name': 'anascacais/ScientISST-notebooks', 'size': '5336'}