Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Onderdelen en Benodigdheden

Weerstand 1k ohm×50
Arduino UNO (of STM32 "Blue Pill" of "Black Pill")×1

Apps en Online Services

  • Arduino IDE

Over dit Project

De R-2R DAC

Eén van de simpelste implementaties van een digitaal-naar-analoog converter kan bereikt worden door een R-2R ladder DAC te ontwerpen. Dit type DAC heeft alleen weerstanden nodig om te werken, wat het een heel beginnersvriendelijke DAC maakt.

Het basisprincipe van dit type DAC is dat je slechts twee waarden voor weerstanden nodig hebt: R en 2R. Je kunt ze opzetten zoals in het schema hieronder getoond.

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

R kan alles zijn zolang elke voorkomens van R in het schema dezelfde waarde heeft.

Bijvoorbeeld, als we R = 1k kiezen, is 2R gewoon twee keer de waarde. In dit geval 2R = 2k. Je kunt dus gewoon 1k en 2k weerstanden gebruiken.

Als je R = 3.3k gebruikt, dan is 2R = 6.6k, enzovoort. Als je gewoon dezelfde weerstandswaarde voor alles wilt gebruiken, dan moet je voor 2R twee weerstanden in serie zetten, wat je componentenaantal verhoogt.

Het aantal bits wordt bepaald door hoeveel 2R-takken er uitsteken. In dit project gebruiken we een 8-bit R-2R en een 6-bit R-2R voor de Arduino Uno of Nano. Als je een andere microcontroller gebruikt die je weet dat volledige poortmanipulatie van minstens 8-bits ondersteunt, zoals de STM32 "Blue Pill" en "Black Pill", dan kun je gewoon twee 8-bit DACs gebruiken.

Zijmerking over DAC ICs:

Dit project richt zich op het gebruik van een R-2R DAC, maar je mag vrij een DAC IC gebruiken om iets vergelijkbaars te bereiken. Als je een DAC IC gaat gebruiken, raad ik aan er eentje te nemen die een snel communicatieprotocol ondersteunt zoals SPI, omdat I2C te traag zal zijn om een gedetailleerde afbeelding te tekenen. Ik zal niet behandelen hoe je een DAC IC gebruikt in deze post, maar misschien in een toekomstige. De R-2R blijft mijn voorkeur omdat het afbeeldingen met meer detail kan uitvoeren.

Poortmanipulatie

We zullen parallelle poortmanipulatie van onze microcontroller gebruiken. De reden hiervoor is dat het een snellere uitvoersnelheid toestaat en de code eenvoudig houdt. Je kunt meer details lezen over de poortregisters voor Arduino hier.

De Arduino Uno en Nano hebben de ATmega328p microcontroller. Deze microcontroller deelt dezelfde pin-mapping met de Atmega168:

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

De poortpinnen en bits worden aangeduid door hun label PXN waar X de poortletter is en N het bitnummer.

Voorbeeld: PB1 is voor PORT B bit 1. Op dezelfde manier is PC5 voor PORT C bit 5.

Als we de pinnen inspecteren, zien we dat de microcontroller poorten B, C en D heeft. Door terug te kijken naar de Arduino-referentie kunnen we zien welke poorten geschreven of gelezen kunnen worden of beide. In ons geval gaan we alleen schrijven.

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

De documentatie stelt dat PORTD lees/schrijf is en gemapt is op digitale pinnen 0 tot 7. Dit geeft ons de volledige 8-bits van de poort om naar te schrijven.

Vervolgens hebben we PORTB, wat volgens de specificatie gemapt is op digitale pinnen 8-13. Een extra opmerking zegt dat bits 6 en 7, die de volledige 8-bits zouden completeren, niet toegankelijk zijn. Deze poort kan alleen gebruikt worden om 6-bits te schrijven.

Hetzelfde geldt voor PORTC. Het is gemapt op analoge pinnen 0-5, maar twee pinnen zijn ook gereserveerd, wat ons slechts 6-bits geeft om naar te schrijven.

Vanwege deze beperkingen moeten we een combinatie gebruiken van een 8-bit DAC voor PORTD en een 6-bit DAC voor PORTC of PORTB.

We zullen PORTD en PORTB gebruiken en nu kunnen we de DACs aan de pinnen verbinden.

Als je visuele hulp nodig hebt bij de montage, zo heb ik beide R-2Rs op het breadboard gemonteerd. Let op dat ik twee R-2Rs gebruikte omdat ik het testte op mijn STM32 "Black Pill". Ik stopte twee jumperdraden eruit zodat ik mijn oscilloscoopsonden eraan kon verbinden en ook een ground-draad aan de kant. Ik gebruikte alle 10k weerstanden, dus voor mijn 2R zette ik twee 10k weerstanden in serie.

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Hier is een nette breadboard-opstelling met Tinkercad. Ik markeerde de uitgangen met X en Y, want dat zullen de oscilloscoopsonden zijn waar we aan verbinden. Als je meer begeleiding nodig hebt bij de opstelling, zal ik schema's geven die de R-2R ladders tonen gemaakt met allemaal dezelfde weerstandswaarden en een andere met twee waarden.

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Controleer je grounds! Elke keer als ik deze opstelling monteer, vergeet ik het. Controleer ook dubbel dat je geen gaten hebt gelaten zonder verbindingen.

Arduino Code

Nu is het tijd voor de Arduino sketch.

Eerst moeten we onze poorten instellen als outputs. Van de Arduino-referentie over poortmanipulatie kunnen we zien hoe we de poorten instellen:

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Eigenlijk zal een waarde van 1 aan het bit het instellen als output en een waarde van 0 als input. Voor PORTD kunnen we direct schrijven omdat alle bits toegankelijk zijn. Voor PORTB, onthoud dat bits 6 en 7 niet bruikbaar zijn omdat ze gemapt zijn op de kristal. Het is goede praktijk om bitwise OR met een waarde van 0 te gebruiken om het wijzigen van bits die niet gezet zullen worden te vermijden.

In onze setup-lus zal dit de code zijn:

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

De for-lus onder de configuraties hermaapt de waarden voor de 6-bit poort. Deze waarden komen uit een lijst die waarden van 8-bit bereik heeft. Om te hermapen naar 6-bits, is onze max waarde 2^6-1 wat 63 is. We mappen vanuit een bereik van 0 tot 2^8-1 wat 255 is. De reden dat we in de Arduino-code hermapen is omdat ons hand-plotter-tool de x en y punten in termen van 8-bits uitvoert. We kunnen het in beide codes wijzigen, maar het is beter om het op de gebruikte microcontroller te doen.

Basisch hebben we enige delay nodig afhankelijk van de oscilloscoop. Ik vond dat voor de mijne 1 prima is. Feitelijk is het weglaten van de delay ook prima. Voor punten, worden ze automatisch gegenereerd door ons hand-plotter-tool, dus je kunt het gewoon kopiëren en plakken, maar dit is eigenlijk hoeveel punten er getekend moeten worden zodat de itererende variabele erdoorheen kan lopen. Nou, hier is de volledige code:

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

De x_points en y_points arrays zullen voor jou elk keer anders zijn als je iets tekent en worden automatisch gegenereerd met ons tool.

Zijmerking over snelle PWM:

Als je een gevorderde gebruiker bent van microcontrollers, kun je beseffen dat als je je zorgen maakt over snelheid, dan kan misschien hetzelfde bereikt worden door snelle PWM en klokregisters te wijzigen. Daarna de PWM-uitgangen voeden naar een laagdoorlaatfilter om een analoog voltage te krijgen, wat het pinnenaantal zou verminderen. Ik heb beide methoden geprobeerd, en dit resulteert nog steeds in betere ondersteuning voor afbeeldingen met meer detail. Tenminste op de Arduino Uno.

Teken Tool

Ik maakte deze tool in Python 3 met tkinter. Als je tkinter niet geïnstalleerd hebt, installeer het met pip.

pip install tk

De code wordt bijgevoegd, maar eigenlijk registreert het de coördinaat op het venster waar je muisklik was. Probeer het venster niet te resizen want dat verandert de resolutie. Als je preciezer wilt zijn, gebruik dan het vergrootglas-tool in Windows. Het venster is gebaseerd op 255x255 omdat dat de maximumwaarden van onze bit-bereiken zijn. Natuurlijk zal één van de dimensies gemapt worden naar 6-bits als je een Arduino UNO gebruikt.

Om de tool aan te roepen, gebruik je dit formaat:

python drawlog.py > arduino_list.txt

Dit creëert een .txt bestand genaamd arduino_list.txt met de Arduino-lijst voor x_points, y_points en NUM_POINTS gegenereerd voor je, klaar om in je code te kopiëren en plakken.

Als voorbeeld, zo ziet het .txt bestand eruit als je het opent. Je hoeft alleen die regels in de code te vervangen.

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Zo ziet het eruit als het geopend is. Daar kun je alles tekenen.

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Ik tekende de volgende afbeelding om het te testen. De code wordt gegenereerd bij het sluiten van het venster.

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

En na het uploaden van de code op de Arduino, zo zag het eruit in X-Y modus.

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

BELANGRIJK:

Als je een compilatiefout krijgt over geheugen, is dit te wijten aan het lage beschikbare geheugen in de Arduino UNO. Dat betekent dat je een minder gedetailleerde afbeelding moet tekenen. Ik denk dat het maximum aantal punten ongeveer 400 was, maar het kan meer zijn. Als je een STM32 "Blue Pill" of "Black Pill" gebruikt, is dit aantal meer dan 4.000.

Oscilloscoop X-Y Modus

De oscilloscoop moet ingesteld worden op X-Y modus. De 8-bit R-2R DAC output (PORTD) wordt verbonden met Kanaal 1 en de 6-bit R-2R DAC (PORTB) met Kanaal 2. Daar kun je het met de knoppen aanpassen tot je een afbeelding ziet.

Dat is het! Als je vragen hebt, voel je vrij om te vragen. Daarnaast, als je het op een Blue Pill of Black Pill wilt uitproberen, hier is de link naar mijn GitHub-pagina met voorbeeldcode.

Nu hier zijn enkele afbeeldingen die ik geplottet heb.

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Voel je vrij om de jouwe te delen!!!

Edit:

Belangrijke Details voor Geheugenbeheer

Als Tim in de reacties aangeeft:

  • In je Arduino-code is je iterator over de punten, t, een "byte" type, wat alleen tot 255 punten ondersteunt. Waarom niet een "int" maken?
  • Je plotter-code geeft "const unsigned long" uit voor x_points en y_points - dat werkt niet omdat je later y-points wijzigt. Ook, waarom niet gewoon "byte" gebruiken om geheugen te besparen?

Wees je bewust van de hardwarebeperkingen die je gebruikt. Voor de Arduino Uno is het beter om byte te gebruiken, maar als je een STM32 of zelfs ESP32 gebruikt, heb je meer punten beschikbaar om te plotten. Bedankt aan allen voor jullie feedback.


Timster:

Ik heb een manier gevonden om het aantal ondersteunde punten op een UNO massaal te verhogen - verplaats ze naar programma-opslagruimte. Je kunt dit doen met de PROGMEM modifier. Op deze manier kun je ongeveer 15.000 punten opslaan!

Dus declareer de arrays zo:

const int NUM_POINTS = ...
const byte x_points[NUM_POINTS] PROGMEM = {...
const byte y_points[NUM_POINTS] PROGMEM = {...

Doe de wijziging aan y_points in de setup-functie niet (dus verwijder de for lus daar). Doe in plaats daarvan een bitshift in de loop-functie.

Je hebt ook een speciaal commando nodig om data uit programma-geheugen te lezen (pgm_read_byte_near). Dus de for-lus in void loop() ziet er zo uit:

for (int t=0; t < NUM_POINTS; t++) // loop door punten
{
  PORTD = pgm_read_byte_near(x_points + t);
  PORTB = pgm_read_byte_near(y_points + t) >> 2;
  delayMicroseconds(FIGURE_DELAY);
}

Dan is het mogelijk om één high-res afbeelding of meerdere kleinere afbeeldingen op te slaan en ertussen te cyclen 😃

Code

Arduino code Arduino

Arduino sketch voor gebruik in een Arduino Uno of Nano board

const byte FIGURE_DELAY = 1; // trace delay in µs. aanpassen indien nodig
const int NUM_POINTS = 87; // aantal XY-punten in figuur
// x en y coördinaten om te plotten
byte x_points[NUM_POINTS] = {106,106,105,104,103,102,101,100,99,98,97,96,95,94,93,92,91,90,90,89,88,87,87,87,86,86,86,86,87,89,90,91,93,95,97,99,101,102,102,104,104,105,105,106,106,106,106,106,106,108,109,110,112,113,115,117,119,121,122,123,123,124,124,124,124,124,123,122,121,120,119,118,117,116,115,114,113,112,111,110,110,109,109,109,108,107,107};
byte y_points[NUM_POINTS] = {78,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,98,99,100,101,103,105,106,108,110,112,113,113,114,115,115,115,115,115,115,114,112,112,110,109,107,106,106,108,110,112,114,114,115,116,116,117,117,117,117,117,116,115,113,112,110,108,106,104,103,102,100,99,98,97,96,95,94,93,92,91,90,89,87,86,84,82,81,80,78};

void setup(){
  // initialiseer poort D en B voor schrijven
  DDRD = B11111111;
  DDRB = B00111111;
  byte t;
  for (t=0; t < NUM_POINTS; t++) {
    y_points[t] = map(y_points[t],0,255,0,63); // hermap Y-punten naar 6 bits omdat poort B beperkt is tot 6 bits op Arduino
  }
}

void loop(){
  for (byte t=0; t < NUM_POINTS; t++) // loop door punten
  {
    PORTD = x_points[t];
    PORTB = y_points[t];
    delayMicroseconds(FIGURE_DELAY);
  }
}

Teken Tool Python

Teken-tool om punten te exporteren voor plotten

import tkinter as tk
X = []
Y = []
lastx, lasty = 0, 0
# xy en addLine zijn alleen voor grafische doeleinden
# on_move_press is de een die de coördinaten logt en Y fixt
def xy(event):
  # logt coördinaten wanneer muis geklikt wordt
  global lastx, lasty
  lastx, lasty = event.x, event.y

def addLine(event):
  # tekent lijn van oud punt naar nieuw punt
  global lastx, lasty
  canvas.create_line((lastx, lasty, event.x, event.y))
  # dit maakt het nieuwe startpunt van de tekening
  lastx, lasty = event.x, event.y

# logt geklikte coördinaat op lijst
def on_move_press(event):
  curX, curY = (event.x, event.y)
  curY = 255 - curY # omdat tkinter andere coördinaten gebruikt
  X.append(str(curX))
  Y.append(str(curY))

# benodigde opstelling voor venster
root = tk.Tk()
root.geometry("255x255")
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
canvas = tk.Canvas(root)
canvas.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))

# bind linkerklik en sleep naar functies en start lus
canvas.bind("", xy)
canvas.bind("", addLine)
root.bind("", on_move_press)
root.mainloop()

# verwijder elke 2e entry om punten te reduceren en trace refresh te verhogen
for i in range(1, int(len(X)/2)):
  X.pop(i)
  Y.pop(i)

print("const int NUM_POINTS = %s;" % str(len(X)))
print("const unsigned long x_points[NUM_POINTS] = {%s};" % ','.join(X))
print("const unsigned long y_points[NUM_POINTS] = {%s};" % ','.join(Y))
# roep aan: python drawlog.py > arduino_list.txt

Schema's

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Aangepaste Visuals op je Oscilloscoop Maken met een R-2R DAC

Productieproces

  1. Een Betaalbaar Draadloos Sensornetwerk Bouwen voor Uw Huis
  2. Je huis temperatuur monitoren met een Raspberry Pi-dashboard
  3. Top accessoires om het volledige potentieel van je Raspberry Pi te ontgrendelen
  4. Bouw een DIY Google Voice HAT voor je Raspberry Pi
  5. Precisie Reactietijd Test met Arduino UNO
  6. De Ultieme Gids voor het Kiezen van de Juiste Bandsaag
  7. Stap-voor-stap handleiding voor het repareren van uw autodeurhandvat
  8. Snelle Gids voor Het Repareren van Roest op Je Auto: Bescherm Je Voertuig
  9. PC Oscilloscoop: Een Goedkope Golfvormanalyser Bouwen met Uw Computer
  10. Weerstanden: Fundamenten, typen en praktische toepassingen
  11. Dynamisch Remmen in Zware Treinen Begrijpen