回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

【雕爷学编程】Arduino动手做(93)--- 0.96寸OLED液晶屏模块10 中等

头像 驴友花雕 2023.07.27 37 1

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来—小小的进步或是搞不掂的问题,希望能够抛砖引玉。

 

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验九十三:0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块

 

42.jpg

  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
 实验九十三: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
 项目三十三:Arduino OLED 频谱分析仪

实验开源代码
 

 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  实验九十七: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
  项目三十三:Arduino OLED 频谱分析仪
  实验接线方法: max9814接A0
  oled模块    Ardunio Uno
  GND---------GND接地线
  VCC---------5V 接电源
  SDA---------A4
  SCL ------- A5
*/

#include <fix_fft.h>                  
#include <ssd1306.h>                  
#include <nano_engine.h>              

// These are user-adjustable
#define LOG_OUTPUT                 // Uncomment to enable logarithmic output (exchanges absolute resoluton for more readable output; may require different below params)
#define SAMPLING_FREQUENCY 15000  // Sampling frequency (Actual max measured frequency captured is half)
#define TIME_FACTOR 2             // Smoothing factor (lower is more dynamic, higher is smoother) ranging from 1 to 10+
#define SCALE_FACTOR 15           // Direct scaling factor (raise for higher bars, lower for shorter bars)

#ifdef LOG_OUTPUT
const float log_scale = 64. / log(64. / SCALE_FACTOR + 1.);    // Attempts to create an equivalent to SCALE_FACTOR for log function
#endif
const float coeff = 1. / TIME_FACTOR;                         // Time smoothing coefficients (used to factor in previous data)
const float anti_coeff = (TIME_FACTOR - 1.) / TIME_FACTOR;
const unsigned int sampling_period_us = round(1000000 * (2.0 / SAMPLING_FREQUENCY)); // Sampling period (doubled to account for overclock)

int8_t data[64], buff[32];                                     // used to store FFT input/output and past data
unsigned long microseconds;                                    // used for timekeeping
int summ, avg;                                                 // used for DC bias elimination

NanoEngine<TILE_32x32_MONO> engine;                            // declares nanoengine

void setup()
{
  OSCCAL = 240; // Overclocks the MCU to around 30 MHz, set lower if this causes instability, raise if you can/want

  ADCSRA &= ~(bit (ADPS0) | bit (ADPS1) | bit (ADPS2));       // clear ADC prescaler bits
  ADCSRA |= bit (ADPS2);                                      // sets ADC clock in excess of 10kHz
  ADCSRA |= bit (ADPS0);

  ssd1306_128x64_i2c_init();                                  // initializes OLED
  ssd1306_clearScreen();                                      // clears OLED

  engine.begin();                                             // inititalizes nanoengine
};

void loop()
{
  summ = 0;
  for (int i = 0; i < 64; i++) {
    microseconds = micros();

    data[i] = ((analogRead(A0)) >> 2) - 128;                        // Fitting analogRead data (range:0 - 1023) to int8_t array (range:-128 - 127)
    summ += data[i];
    while (micros() < (microseconds + sampling_period_us)) {        // Timing out uC ADC to fulfill sampling frequency requirement
    }
  }

  // Eliminating remaining DC component (produces usable data in FFT bin #0, which is usually swamped by DC bias)
  avg = summ / 64;
  for (int i = 0; i < 64; i++) {
    data[i] -= avg;
  }

  fix_fftr(data, 6, 0);                             // Performing real FFT

  // Time smoothing by user-determined factor and user-determined scaling
  for (int count = 0; count < 32; count++) {
    if (data[count] < 0) data[count] = 0;                                         // Eliminating negative output of fix_fftr
#ifdef LOG_OUTPUT
    else data[count] = log_scale * log((float)(data[count] + 1));                 // Logarithmic function equivalent to SCALING_FACTOR*log2(x+1)
#else
    else data[count] *= SCALE_FACTOR;                                             // Linear scaling up according to SCALE_FACTOR
#endif
    data[count] = (float)buff[count] * anti_coeff + (float)data[count] * coeff;   // Smoothing by factoring in past data
    buff[count] = data[count];                                                    // Storing current output as next frame's past data
    if (data[count] > 63) data[count] = 63;                                       // Capping output at screen height
  }

  // Output to SSD1306 using nanoengine canvas from library
  engine.refresh();                                               // Mark entire screen to be refreshed
  engine.canvas.clear();                                          // Clear canvas as previous data
  for (int i = 0; i < 8; i++) {
    engine.canvas.drawVLine(i * 4, 31 - (data[i] + 1), 31);  // Draw to canvas data for lower-leftest sector (FFT bins 0 - 7, lower half)
  }
  engine.canvas.blt(0, 32);                                       // Outputs canvas to OLED with an offset (x pixels, y pixels)
  engine.canvas.clear();
  for (int i = 0; i < 8; i++) {
    if (data[i] > 31) engine.canvas.drawVLine(i * 4, 31 - (data[i] - 31), 31); // Draw to canvas data for upper-leftest sector (FFT bins 0 - 7, upper half)
  }
  engine.canvas.blt(0, 0);
  engine.canvas.clear();
  for (int i = 8; i < 16; i++) {
    engine.canvas.drawVLine((i - 8) * 4, 31 - (data[i] + 1), 31); // FFT bins 8 - 15, lower half
  }
  engine.canvas.blt(32, 32);
  engine.canvas.clear();
  for (int i = 8; i < 16; i++) {
    if (data[i] > 31) engine.canvas.drawVLine((i - 8) * 4, 31 - (data[i] - 31), 31); // FFT bins 9 - 15, upper half
  }
  engine.canvas.blt(32, 0);
  engine.canvas.clear();
  for (int i = 16; i < 24; i++) {
    engine.canvas.drawVLine((i - 16) * 4, 31 - (data[i] + 1), 31); // FFT bins 16 - 23, lower half
  }
  engine.canvas.blt(64, 32);
  engine.canvas.clear();
  for (int i = 16; i < 24; i++) {
    if (data[i] > 31) engine.canvas.drawVLine((i - 16) * 4, 31 - (data[i] - 31), 31); // FFT bins 16 - 23, upper half
  }
  engine.canvas.blt(64, 0);
  engine.canvas.clear();
  for (int i = 24; i < 32; i++) {
    engine.canvas.drawVLine((i - 24) * 4, 31 - (data[i] + 1), 31); // FFT bins 24 - 31, lower half
  }
  engine.canvas.blt(96, 32);
  engine.canvas.clear();
  for (int i = 24; i < 32; i++) {
    if (data[i] > 31) engine.canvas.drawVLine((i - 24) * 4, 31 - (data[i] - 31), 31); // FFT bins 24 - 31, upper half
  }
  engine.canvas.blt(96, 0);
}

Arduino实验场景图

 

126.jpg

  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
 实验九十七: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
 
 项目三十三:Arduino OLED 频谱分析仪(视频,法语版《因为爱情》3分12秒)
 https://v.youku.com/v_show/id_XNTgwNzY3ODkwNA==.html?spm=a2hcb.playlsit.page.1


 

  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
 实验九十三: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
 项目三十四:OLED FeatherWing测试

 实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  实验九十七: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
  项目三十四:OLED FeatherWing测试
  实验接线方法: 
  oled模块    Ardunio Uno
  GND---------GND接地线
  VCC---------5V 接电源
  SDA---------A4
  SCL ------- A5
*/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);

// OLED FeatherWing buttons map to different pins depending on board:
#if defined(ESP8266)
  #define BUTTON_A  0
  #define BUTTON_B 16
  #define BUTTON_C  2
#elif defined(ESP32)
  #define BUTTON_A 15
  #define BUTTON_B 32
  #define BUTTON_C 14
#elif defined(ARDUINO_STM32_FEATHER)
  #define BUTTON_A PA15
  #define BUTTON_B PC7
  #define BUTTON_C PC5
#elif defined(TEENSYDUINO)
  #define BUTTON_A  4
  #define BUTTON_B  3
  #define BUTTON_C  8
#elif defined(ARDUINO_FEATHER52832)
  #define BUTTON_A 31
  #define BUTTON_B 30
  #define BUTTON_C 27
#else // 32u4, M0, M4, nrf52840 and 328p
  #define BUTTON_A  9
  #define BUTTON_B  6
  #define BUTTON_C  5
#endif

void setup() {
  Serial.begin(9600);

  Serial.println("OLED FeatherWing test");
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x32

  Serial.println("OLED begun");

  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(1000);

  // Clear the buffer.
  display.clearDisplay();
  display.display();

  Serial.println("IO test");

  pinMode(BUTTON_A, INPUT_PULLUP);
  pinMode(BUTTON_B, INPUT_PULLUP);
  pinMode(BUTTON_C, INPUT_PULLUP);

  // text display tests
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0,0);
  display.print("Connecting to SSID\n'adafruit':");
  display.print("connected!");
  display.println("IP: 10.0.1.23");
  display.println("Sending val #0");
  display.setCursor(0,0);
  display.display(); // actually display all of the above
}

void loop() {
  if(!digitalRead(BUTTON_A)) display.print("A");
  if(!digitalRead(BUTTON_B)) display.print("B");
  if(!digitalRead(BUTTON_C)) display.print("C");
  delay(10);
  yield();
  display.display();
}

实验串口返回情况

 

127.jpg

Arduino实验场景图

 

128.jpg

  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
 实验九十三: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
 项目三十五:一个漂亮、便宜、低开销的文本显示

 实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+图形编程+仿真编程)
  实验九十七: 0.96寸I2C IIC通信128*64显示器 OLED液晶屏模块
  项目三十五:一个漂亮、便宜、低开销的文本显示
  实验接线方法:
  oled模块    Ardunio Uno
  GND---------GND接地线
  VCC---------5V 接电源
  SDA---------D8
  SCL ------- D9
*/

#include <evilOLED.h>

void setup() {
  // set SDA + SCL pins as output
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
}

void loop() {
  evilOLED disp(8, 9); // initialize the display (SDA,SCL)
  delay(1000);

  disp.cls(0x00); // clears screen
  delay(500);

  disp.setCursor(2, 2); // sets text cursor (x,y)
  disp.putString("HELLO EAGLER8"); // Strings MUST be double quoted and capitalized if using default font
  delay(500);

  disp.alert(120); // flashes display 3 times
  delay(1500);

  disp.setCursor(5, 4);
  disp.putString(12345); // putString also accepts ints
  delay(1500);
}

Arduino实验场景图

 

129.jpg

 

 

##这个库会做的事情 使用存储在 Arduino PROGMEM 中的字体文件,这个库可以初始化显示并执行以下操作:

在屏幕上的 x,y (0-16,0-7) 位置显示(有限)文本在屏幕上的 x,y (0-16,0-7) 位置显示整数当您控制字体时,您可以编写您喜欢的任何字符!包含用于生成字体和/或闪屏数据的实用程序 python 脚本闪屏(具有指定的延迟)警报模式(随着延迟的减少闪烁多次)集成软件 2 针 I2C 通信,将 Arduino SDA/SCL 留作其他用途
 

##这个库最终可能会做的事情(路线图)

支持双高字体打印支持倒排文本支持滚动模式putString() 直接支持 float/double使用可选的帧缓冲区(仅在启用时才使用内存)各种图形功能将成为可能与上述

 

130.jpg

评论

user-avatar
  • hacker_

    hacker_2023.07.27

    666

    0
    icon 他的勋章
      展开更多