Tous les tutoriels

4 · Écrans & bus

OLED : tracer une courbe

Expert30 min

Objectif

Afficher en direct la valeur de A0 sous forme d'oscillogramme.

Pourquoi c'est utile

Vous transformez la carte en instrument de mesure autonome.

Étapes

  1. 01Partez du sketch OLED.
  2. 02Mémorisez 128 échantillons dans un tableau circulaire.
  3. 03Convertissez chaque valeur en hauteur de pixel (0–63).
  4. 04Redessinez la trame à chaque rafraîchissement.

Code de départ

// OLED Hello — SSD1306 128x64 over I2C (SDA = A4, SCL = A5).
// The cloud toolchain ships only <Wire.h>, so this sketch includes a tiny
// built-in SSD1306 driver: no external libraries needed.

#include <Wire.h>

#define OLED_ADDR 0x3C

static const uint8_t FONT5X7[] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00,
  0x14, 0x7f, 0x14, 0x7f, 0x14, 0x24, 0x2a, 0x7f, 0x2a, 0x12, 0x23, 0x13, 0x08, 0x64, 0x62,
  0x36, 0x49, 0x56, 0x20, 0x50, 0x00, 0x08, 0x07, 0x03, 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,
  0x00, 0x41, 0x22, 0x1c, 0x00, 0x2a, 0x1c, 0x7f, 0x1c, 0x2a, 0x08, 0x08, 0x3e, 0x08, 0x08,
  0x00, 0x80, 0x70, 0x30, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x60, 0x60, 0x00,
  0x20, 0x10, 0x08, 0x04, 0x02, 0x3e, 0x51, 0x49, 0x45, 0x3e, 0x00, 0x42, 0x7f, 0x40, 0x00,
  0x72, 0x49, 0x49, 0x49, 0x46, 0x21, 0x41, 0x49, 0x4d, 0x33, 0x18, 0x14, 0x12, 0x7f, 0x10,
  0x27, 0x45, 0x45, 0x45, 0x39, 0x3c, 0x4a, 0x49, 0x49, 0x31, 0x41, 0x21, 0x11, 0x09, 0x07,
  0x36, 0x49, 0x49, 0x49, 0x36, 0x46, 0x49, 0x49, 0x29, 0x1e, 0x00, 0x00, 0x14, 0x00, 0x00,
  0x00, 0x40, 0x34, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x41, 0x14, 0x14, 0x14, 0x14, 0x14,
  0x00, 0x41, 0x22, 0x14, 0x08, 0x02, 0x01, 0x59, 0x09, 0x06, 0x3e, 0x41, 0x5d, 0x59, 0x4e,
  0x7c, 0x12, 0x11, 0x12, 0x7c, 0x7f, 0x49, 0x49, 0x49, 0x36, 0x3e, 0x41, 0x41, 0x41, 0x22,
  0x7f, 0x41, 0x41, 0x41, 0x3e, 0x7f, 0x49, 0x49, 0x49, 0x41, 0x7f, 0x09, 0x09, 0x09, 0x01,
  0x3e, 0x41, 0x41, 0x51, 0x73, 0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00, 0x41, 0x7f, 0x41, 0x00,
  0x20, 0x40, 0x41, 0x3f, 0x01, 0x7f, 0x08, 0x14, 0x22, 0x41, 0x7f, 0x40, 0x40, 0x40, 0x40,
  0x7f, 0x02, 0x1c, 0x02, 0x7f, 0x7f, 0x04, 0x08, 0x10, 0x7f, 0x3e, 0x41, 0x41, 0x41, 0x3e,
  0x7f, 0x09, 0x09, 0x09, 0x06, 0x3e, 0x41, 0x51, 0x21, 0x5e, 0x7f, 0x09, 0x19, 0x29, 0x46,
  0x26, 0x49, 0x49, 0x49, 0x32, 0x03, 0x01, 0x7f, 0x01, 0x03, 0x3f, 0x40, 0x40, 0x40, 0x3f,
  0x1f, 0x20, 0x40, 0x20, 0x1f, 0x3f, 0x40, 0x38, 0x40, 0x3f, 0x63, 0x14, 0x08, 0x14, 0x63,
  0x03, 0x04, 0x78, 0x04, 0x03, 0x61, 0x59, 0x49, 0x4d, 0x43, 0x00, 0x7f, 0x41, 0x41, 0x41,
  0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x41, 0x41, 0x41, 0x7f, 0x04, 0x02, 0x01, 0x02, 0x04,
  0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x03, 0x07, 0x08, 0x00, 0x20, 0x54, 0x54, 0x78, 0x40,
  0x7f, 0x28, 0x44, 0x44, 0x38, 0x38, 0x44, 0x44, 0x44, 0x28, 0x38, 0x44, 0x44, 0x28, 0x7f,
  0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x08, 0x7e, 0x09, 0x02, 0x18, 0xa4, 0xa4, 0x9c, 0x78,
  0x7f, 0x08, 0x04, 0x04, 0x78, 0x00, 0x44, 0x7d, 0x40, 0x00, 0x20, 0x40, 0x40, 0x3d, 0x00,
  0x7f, 0x10, 0x28, 0x44, 0x00, 0x00, 0x41, 0x7f, 0x40, 0x00, 0x7c, 0x04, 0x78, 0x04, 0x78,
  0x7c, 0x08, 0x04, 0x04, 0x78, 0x38, 0x44, 0x44, 0x44, 0x38, 0xfc, 0x18, 0x24, 0x24, 0x18,
  0x18, 0x24, 0x24, 0x18, 0xfc, 0x7c, 0x08, 0x04, 0x04, 0x08, 0x48, 0x54, 0x54, 0x54, 0x24,
  0x04, 0x04, 0x3f, 0x44, 0x24, 0x3c, 0x40, 0x40, 0x20, 0x7c, 0x1c, 0x20, 0x40, 0x20, 0x1c,
  0x3c, 0x40, 0x30, 0x40, 0x3c, 0x44, 0x28, 0x10, 0x28, 0x44, 0x4c, 0x90, 0x90, 0x90, 0x7c,
  0x44, 0x64, 0x54, 0x4c, 0x44, 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00,
  0x00, 0x41, 0x36, 0x08, 0x00, 0x02, 0x01, 0x02, 0x04, 0x02
};

void oledCmd(uint8_t c) {
  Wire.beginTransmission(OLED_ADDR);
  Wire.write(0x00);
  Wire.write(c);
  Wire.endTransmission();
}

void oledInit() {
  Wire.begin();
  const uint8_t init[] = {
    0xAE, 0xD5, 0x80, 0xA8, 0x3F, 0xD3, 0x00, 0x40,
    0x8D, 0x14, 0x20, 0x00, 0xA1, 0xC8, 0xDA, 0x12,
    0x81, 0xCF, 0xD9, 0xF1, 0xDB, 0x40, 0xA4, 0xA6, 0xAF
  };
  for (uint8_t i = 0; i < sizeof(init); i++) oledCmd(init[i]);
}

void oledWindow(uint8_t col, uint8_t page, uint8_t width) {
  oledCmd(0x21); oledCmd(col); oledCmd(col + width - 1);
  oledCmd(0x22); oledCmd(page); oledCmd(page);
}

void oledClear() {
  oledCmd(0x21); oledCmd(0); oledCmd(127);
  oledCmd(0x22); oledCmd(0); oledCmd(7);
  for (uint16_t i = 0; i < 1024; i += 16) {
    Wire.beginTransmission(OLED_ADDR);
    Wire.write(0x40);
    for (uint8_t j = 0; j < 16; j++) Wire.write(0x00);
    Wire.endTransmission();
  }
}

// Prints text at a character cell. scale = 1 (5x7) or 2 (10x14).
void oledText(uint8_t col, uint8_t page, const char *text, uint8_t scale) {
  for (uint8_t row = 0; row < scale; row++) {
    uint8_t x = col;
    oledWindow(col, page + row, 128 - col);
    Wire.beginTransmission(OLED_ADDR);
    Wire.write(0x40);
    uint8_t sent = 0;
    for (const char *p = text; *p && x < 128; p++) {
      for (uint8_t i = 0; i < 6; i++) {
        uint8_t bits = (i < 5 && *p >= 32) ? pgm_read_byte(&FONT5X7[(*p - 32) * 5 + i]) : 0x00;
        uint8_t slice = 0;
        for (uint8_t b = 0; b < 8; b++) {
          uint8_t src = (row * 8 + b) / scale;
          if (src < 8 && (bits >> src) & 1) slice |= (1 << b);
        }
        for (uint8_t s = 0; s < scale && x < 128; s++) {
          Wire.write(slice);
          x++;
          if (++sent >= 16) { Wire.endTransmission(); Wire.beginTransmission(OLED_ADDR); Wire.write(0x40); sent = 0; }
        }
      }
    }
    Wire.endTransmission();
  }
}

int counter = 0;

void setup() {
  Serial.begin(9600);
  oledInit();
  oledClear();
  oledText(4, 0, "Circuitly", 2);
  oledText(4, 3, "SSD1306 over I2C", 1);
  Serial.println("OLED ready");
}

void loop() {
  char line[24];
  snprintf(line, sizeof(line), "uptime: %lu s", millis() / 1000);
  oledText(4, 5, line, 1);
  snprintf(line, sizeof(line), "frames: %d   ", counter++);
  oledText(4, 6, line, 1);
  delay(500);
}

Ce tutoriel se réalise dans le simulateur Circuitly : le montage et le code sont vérifiés automatiquement à chaque étape.

Tutoriels suivants