Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Construa um Mini Osciloscópio DIY com Arduino Nano – Tutorial Passo a Passo

Componentes e Materiais

Arduino Nano R3 1
Display OLED 0.96" SSD1306 64x128 (ElectroPeak) 1
Chave tátil (Top Actuated) 9
Diodo 1N4148 – Chaveamento Rápido 4

Aplicativos e Serviços Online

Sobre o Projeto

Neste vídeo, mostro como fazer seu próprio mini osciloscópio em casa. É simples e fácil de montar. O código não é meu; apenas criei o tutorial. Para este projeto, dependi de código de terceiros, cujo link está abaixo. Se tiver dúvidas ou sugestões, comente no meu vídeo no YouTube e não esqueça de curtir e se inscrever no canal.

Clique aqui para tutorial completo e código fonte

Meu Instagram: @pm.goharian

Componentes Necessários

O que é um Osciloscópio?

Um osciloscópio, antigamente chamado de oscilógrafo, e informalmente conhecido como scope ou o-scope, CRO (osciloscópio de raios catódicos) ou DSO (osciloscópio digital de armazenamento), é um instrumento de teste eletrônico que exibe graficamente sinais variáveis [tensões], geralmente como um gráfico bidimensional de um ou mais sinais em função do tempo. Outros sinais (som, vibração) podem ser convertidos em tensões e exibidos.

Osciloscópios mostram a variação de um sinal elétrico ao longo do tempo, com tensão no eixo Y e tempo no eixo X, em escala calibrada. A forma de onda pode ser analisada para propriedades como amplitude, frequência, tempo de subida, intervalo de tempo, distorção, entre outras. Instrumentos digitais modernos calculam e exibem essas propriedades diretamente. Originalmente, exigia medição manual da forma de onda contra as escalas na tela do instrumento.

Esquemáticos do Projeto

Nota: Certifique-se de que todas as conexões do seu circuito são exatamente iguais aos esquemáticos.

Construa um Mini Osciloscópio DIY com Arduino Nano – Tutorial Passo a Passo

Construa um Mini Osciloscópio DIY com Arduino Nano – Tutorial Passo a Passo

Construa um Mini Osciloscópio DIY com Arduino Nano – Tutorial Passo a Passo

Referências:

Código

Código Principal (C/C++)

/* (_20190212_OLEDoscilloscope.ino) 1285byte ram free 2019/02/12 */
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <avr/pgmspace.h> // PROGMEM
#include <EEPROM.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define REC_LENGTH 200

#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const char vRangeName[10][5] PROGMEM = {"A50V", "A 5V", " 50V", " 20V", " 10V", " 5V", " 2V", " 1V", "0.5V", "0.2V"};
const char * const vstring_table[] PROGMEM = {vRangeName[0], vRangeName[1], vRangeName[2], vRangeName[3], vRangeName[4], vRangeName[5], vRangeName[6], vRangeName[7], vRangeName[8], vRangeName[9]};
const char hRangeName[8][6] PROGMEM = {" 50ms", " 20ms", " 10ms", " 5ms", " 2ms", " 1ms", "500us", "200us"};
const char * const hstring_table[] PROGMEM = {hRangeName[0], hRangeName[1], hRangeName[2], hRangeName[3], hRangeName[4], hRangeName[5], hRangeName[6], hRangeName[7]};

int waveBuff[REC_LENGTH];
char chrBuff[10];
String hScale = "xxxAs";
String vScale = "xxxx";
float lsb5V = 0.0055549;
float lsb50V = 0.051513;
volatile int vRange;
volatile int hRange;
volatile int trigD;
volatile int scopeP;
volatile boolean hold = false;
volatile boolean paraChanged = false;
volatile int saveTimer;
int timeExec;
int dataMin;
int dataMax;
int dataAve;
int rangeMax;
int rangeMin;
int rangeMaxDisp;
int rangeMinDisp;
int trigP;
boolean trigSync;
int att10x;

void setup() {
  pinMode(2, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT);
  pinMode(13, OUTPUT);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    for (;;);
  }
  loadEEPROM();
  analogReference(INTERNAL);
  attachInterrupt(0, pin2IRQ, FALLING);
  startScreen();
}

void loop() {
  digitalWrite(13, HIGH);
  setConditions();
  readWave();
  digitalWrite(13, LOW);
  dataAnalize();
  writeCommonImage();
  plotData();
  dispInf();
  display.display();
  saveEEPROM();
  while (hold == true) {
    dispHold();
    delay(10);
  }
}

void setConditions() {
  strcpy_P(chrBuff, (char*)pgm_read_word(&(hstring_table[hRange])));
  hScale = chrBuff;
  strcpy_P(chrBuff, (char*)pgm_read_word(&(vstring_table[vRange])));
  vScale = chrBuff;

  switch (vRange) {
    case 0: { rangeMax = 1023; rangeMin = 0; att10x = 1; break; }
    case 1: { rangeMax = 1023; rangeMin = 0; att10x = 0; break; }
    case 2: { rangeMax = 50 / lsb50V; rangeMaxDisp = 5000; rangeMin = 0; rangeMinDisp = 0; att10x = 1; break; }
    case 3: { rangeMax = 20 / lsb50V; rangeMaxDisp = 2000; rangeMin = 0; rangeMinDisp = 0; att10x = 1; break; }
    case 4: { rangeMax = 10 / lsb50V; rangeMaxDisp = 1000; rangeMin = 0; rangeMinDisp = 0; att10x = 1; break; }
    case 5: { rangeMax = 5 / lsb5V; rangeMaxDisp = 500; rangeMin = 0; rangeMinDisp = 0; att10x = 0; break; }
    case 6: { rangeMax = 2 / lsb5V; rangeMaxDisp = 200; rangeMin = 0; rangeMinDisp = 0; att10x = 0; break; }
    case 7: { rangeMax = 1 / lsb5V; rangeMaxDisp = 100; rangeMin = 0; rangeMinDisp = 0; att10x = 0; break; }
    case 8: { rangeMax = 0.5 / lsb5V; rangeMaxDisp = 50; rangeMin = 0; rangeMinDisp = 0; att10x = 0; break; }
    case 9: { rangeMax = 0.2 / lsb5V; rangeMaxDisp = 20; rangeMin = 0; rangeMinDisp = 0; att10x = 0; break; }
  }
}

void writeCommonImage() {
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setCursor(86, 0);
  display.println(F("av V"));
  display.drawFastVLine(26, 9, 55, WHITE);
  display.drawFastVLine(127, 9, 55, WHITE);
  display.drawFastHLine(24, 9, 7, WHITE);
  display.drawFastHLine(24, 36, 2, WHITE);
  display.drawFastHLine(24, 63, 7, WHITE);
  display.drawFastHLine(51, 9, 3, WHITE);
  display.drawFastHLine(51, 63, 3, WHITE);
  display.drawFastHLine(76, 9, 3, WHITE);
  display.drawFastHLine(76, 63, 3, WHITE);
  display.drawFastHLine(101, 9, 3, WHITE);
  display.drawFastHLine(101, 63, 3, WHITE);
  display.drawFastHLine(123, 9, 5, WHITE);
  display.drawFastHLine(123, 63, 5, WHITE);
  for (int x = 26; x <= 128; x += 5) display.drawFastHLine(x, 36, 2, WHITE);
  for (int x = (127 - 25); x > 30; x -= 25) {
    for (int y = 10; y < 63; y += 5) display.drawFastVLine(x, y, 2, WHITE);
  }
}

void readWave() {
  if (att10x == 1) { pinMode(12, OUTPUT); digitalWrite(12, LOW); }
  else { pinMode(12, INPUT); }

  switch (hRange) {
    case 0: { timeExec = 400 + 50; ADCSRA = (ADCSRA & 0xf8) | 0x07; for (int i=0;i dataMax) dataMax = d;
  }
  dataAve = (sum + 10) / 20;

  if (vRange <= 1) {
    rangeMin = dataMin - 20; rangeMin = (rangeMin / 10) * 10; if (rangeMin < 0) rangeMin = 0;
    rangeMax = dataMax + 20; rangeMax = ((rangeMax / 10) + 1) * 10; if (rangeMax > 1020) rangeMax = 1023;
    if (att10x == 1) { rangeMaxDisp = 100 * (rangeMax * lsb50V); rangeMinDisp = 100 * (rangeMin * lsb50V); }
    else { rangeMaxDisp = 100 * (rangeMax * lsb5V); rangeMinDisp = 100 * (rangeMin * lsb5V); }
  }

  for (trigP = (REC_LENGTH/2)-51; trigP < (REC_LENGTH/2)+50; trigP++) {
    if (trigD == 0) {
      if ((waveBuff[trigP-1] < (dataMax+dataMin)/2) && (waveBuff[trigP] >= (dataMax+dataMin)/2)) break;
    } else {
      if ((waveBuff[trigP-1] > (dataMax+dataMin)/2) && (waveBuff[trigP] <= (dataMax+dataMin)/2)) break;
    }
  }
  trigSync = true;
  if (trigP >= (REC_LENGTH/2)+50) { trigP = REC_LENGTH/2; trigSync = false; }
}

void startScreen() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(10, 25);
  display.println(F("PM.GOHARIAN"));
  display.setCursor(10, 45);
  display.println(F("Pen oscope"));
  display.display();
  delay(5000);
  display.clearDisplay();
  display.setTextSize(1);
}

void dispHold() {
  display.fillRect(32, 12, 24, 8, BLACK);
  display.setCursor(32, 12);
  display.print(F("Hold"));
  display.display();
}

void dispInf() {
  float voltage;
  display.setCursor(2, 0);
  display.print(vScale);
  if (scopeP == 0) { display.drawFastHLine(0, 7, 27, WHITE); display.drawFastVLine(0, 5, 2, WHITE); display.drawFastVLine(26, 5, 2, WHITE); }
  display.setCursor(34, 0);
  display.print(hScale);
  if (scopeP == 1) { display.drawFastHLine(32, 7, 33, WHITE); display.drawFastVLine(32, 5, 2, WHITE); display.drawFastVLine(64, 5, 2, WHITE); }
  display.setCursor(75, 0);
  if (trigD == 0) display.print(char(0x18)); else display.print(char(0x19));
  if (scopeP == 2) { display.drawFastHLine(71, 7, 13, WHITE); display.drawFastVLine(71, 5, 2, WHITE); display.drawFastVLine(83, 5, 2, WHITE); }

  if (att10x == 1) voltage = dataAve * lsb50V / 10.0;
  else voltage = dataAve * lsb5V / 10.0;
  dtostrf(voltage, 4, 2, chrBuff);
  display.setCursor(98, 0);
  display.print(chrBuff);

  voltage = rangeMaxDisp / 100.0;
  if (vRange == 1 || vRange > 4) dtostrf(voltage, 4, 2, chrBuff); else dtostrf(voltage, 4, 1, chrBuff);
  display.setCursor(0, 9); display.print(chrBuff);

  voltage = (rangeMaxDisp + rangeMinDisp) / 200.0;
  if (vRange == 1 || vRange > 4) dtostrf(voltage, 4, 2, chrBuff); else dtostrf(voltage, 4, 1, chrBuff);
  display.setCursor(0, 33); display.print(chrBuff);

  voltage = rangeMinDisp / 100.0;
  if (vRange == 1 || vRange > 4) dtostrf(voltage, 4, 2, chrBuff); else dtostrf(voltage, 4, 1, chrBuff);
  display.setCursor(0, 57); display.print(chrBuff);

  if (!trigSync) { display.setCursor(60, 55); display.print(F("Unsync")); }
}

void plotData() {
  for (int x=0; x<=98; x++) {
    long y1 = map(waveBuff[x + trigP - 50], rangeMin, rangeMax, 63, 9);
    long y2 = map(waveBuff[x + trigP - 49], rangeMin, rangeMax, 63, 9);
    y1 = constrain(y1, 9, 63); y2 = constrain(y2, 9, 63);
    display.drawLine(x+27, y1, x+28, y2, WHITE);
  }
}

void saveEEPROM() {
  if (paraChanged) {
    saveTimer -= timeExec;
    if (saveTimer < 0) {
      paraChanged = false;
      EEPROM.write(0, vRange);
      EEPROM.write(1, hRange);
      EEPROM.write(2, trigD);
      EEPROM.write(3, scopeP);
    }
  }
}

void loadEEPROM() {
  int x = EEPROM.read(0); if (x<0 || x>9) x=3; vRange=x;
  x = EEPROM.read(1); if (x<0 || x>7) x=3; hRange=x;
  x = EEPROM.read(2); if (x<0 || x>1) x=1; trigD=x;
  x = EEPROM.read(3); if (x<0 || x>2) x=1; scopeP=x;
}

void pin2IRQ() {
  int x = PINB;
  if ((x & 0x07) != 0x07) { saveTimer = 5000; paraChanged = true; }
  if ((x & 0x01) == 0) { scopeP++; if (scopeP>2) scopeP=0; }
  if ((x & 0x02) == 0) {
    if (scopeP==0) { vRange++; if (vRange>9) vRange=9; }
    if (scopeP==1) { hRange++; if (hRange>7) hRange=7; }
    if (scopeP==2) { trigD=0; }
  }
  if ((x & 0x04) == 0) {
    if (scopeP==0) { vRange--; if (vRange<0) vRange=0; }
    if (scopeP==1) { hRange--; if (hRange<0) hRange=0; }
    if (scopeP==2) { trigD=1; }
  }
  if ((x & 0x08) == 0) { hold = !hold; }
}

Esquemáticos

Construa um Mini Osciloscópio DIY com Arduino Nano – Tutorial Passo a Passo

Processo de manufatura

  1. Construa Sua Própria Máquina de Escrever Deveres de Casa (Plotter de Caneta) em Casa
  2. Console de Controle DIY para Photoshop com Arduino Nano RP2040
  3. Fabricação Artesanal de Fibra de Carbono: Guia Passo a Passo para Criar Peças em Casa
  4. Crie um Sistema Ambilight Impressionante para Monitor com Arduino
  5. Crie um Botão de Teclado "Socável" Personalizado com Arduino: Guia Passo a Passo
  6. Medir a Massa da Terra com Arduino: Guia DIY Passo a Passo
  7. Interface Web em PHP para Controlar Arduino Uno via Ethernet Shield
  8. Criar Tons Musicais com Arduino: Um Guia Passo a Passo
  9. Porta Automática com Arduino e Sensor Ultrassônico HC-SR04
  10. Construa uma Bússola Digital em Tempo Real com Arduino e Processing