LoginSignup
0
0

More than 1 year has passed since last update.

STM32F401(Black Pill)にSD・ssd1306・LM35と色々詰め込んでみた

Posted at

 400穴ブレッドボード上のSTM32F401CCU6(Black Pill)にどれだけ詰め込めるか試しました。ArduinoIDEを使いmicroSDカードスロット、SSD1306OLED、温度センサーLM35CZを載せて動かしてみました。
F401Many.jpg

Adafruitのssd1306_128x64_i2cのexampleに、SDライブラリー、温度を読取る簡単なコードを加えてbinの62.88KBのサイズでした。なかなかの大きさになりましたがまだ余裕ですかね。相変わらず、このボードを「STM32 BOOTLOADER」に変化させるのに世話が焼けます。
 内容は、まずSDカードからファイルリストを取得表示させ、次にお決まりのグラフィックスを表示、loopで温度を取得表示という、たいして芸の無いものです。温度の較正のため私の部屋の温度に合うよう適当に
 temp_val = (temp_adc_val * 3.00/10)
としてあります。1度ぐらいは常にずれてきますが。
 今回初めて、display.cp437(true or false)を意識しましたが、「0xB0」に一文字入るかどうかの違いです。温度の「°」を表すために「248」を使いました。
 以下にソースを示しますが、描画の関数群は省略します。ただし、スノーフレークの部分はdelay(50)とし、無限ループを100回ループに変更し、loopに進むようにしました。

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

#define SCREEN_WIDTH 128  // OLED display width, in pixels
#define SCREEN_HEIGHT 64  // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
#define OLED_RESET -1        // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C  ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NUMFLAKES 10  // Number of snowflakes in the animation example

#define LOGO_HEIGHT 16
#define LOGO_WIDTH 16
static const unsigned char
  PROGMEM logo_bmp[] = {
    0b00000000, 0b11000000,
    0b00000001, 0b11000000,
    0b00000001, 0b11000000,
    0b00000011, 0b11100000,
    0b11110011, 0b11100000,
    0b11111110, 0b11111000,
    0b01111110, 0b11111111,
    0b00110011, 0b10011111,
    0b00011111, 0b11111100,
    0b00001101, 0b01110000,
    0b00011011, 0b10100000,
    0b00111111, 0b11100000,
    0b00111111, 0b11110000,
    0b01111100, 0b11110000,
    0b01110000, 0b01110000,
    0b00000000, 0b00110000
  };
/*
  SD card attached to SPI bus as follows:
  ** MOSI - pin 11
  ** MISO - pin 12
  ** CLK  - pin 13
  ** CS   - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
*/
// STM32F401CCU6
#define MOSI PA7
#define MISO PA6
#define CLK  PA5
#define CS   PA4

#define lm35_pin PA1	/* LM35 O/P pin */

File root;

void setup() {
  Serial.begin(115200);
  Wire.setSDA(PB7);
  Wire.setSCL(PB6);
  Wire.begin();

  while (!Serial) {
    ;  // wait for serial port to connect. Needed for native USB port only
  }

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;  // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000);  // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  // Draw a single pixel in white
  display.drawPixel(10, 10, SSD1306_WHITE);

  // Show the display buffer on the screen. You MUST call display() after
  // drawing commands to make them visible on screen!
  display.display();
  delay(2000);
  // display.display() is NOT necessary after every single drawing command,
  // unless that's what you want...rather, you can batch up a bunch of
  // drawing operations and then update the screen all at once by calling
  // display.display(). These examples demonstrate both approaches...
  
  display.clearDisplay();
  display.setTextSize(1);               // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);  // Draw white text
  display.setCursor(0, 0);              // Start at top-left corner
  display.cp437(true);                  // Use full 256 char 'Code Page 437' font
  
  Serial.print("Initializing SD card...");
  display.print("Initializing SD card...");
  if (!SD.begin(CS)) {
    Serial.println("initialization failed!");
    display.println("initialization failed!");
    delay(1000);
  } else {
    Serial.println("initialization done.");
    display.println("initialization done.");
    root = SD.open("/");
    printDirectory(root, 0);
    Serial.println("done!");
    display.println("done!");
  }
  display.display();
  delay(5000);
  display.clearDisplay();

  testdrawline();  // Draw many lines

  testdrawrect();  // Draw rectangles (outlines)

  testfillrect();  // Draw rectangles (filled)

  testdrawcircle();  // Draw circles (outlines)

  testfillcircle();  // Draw circles (filled)

  testdrawroundrect();  // Draw rounded rectangles (outlines)

  testfillroundrect();  // Draw rounded rectangles (filled)

  testdrawtriangle();  // Draw triangles (outlines)

  testfilltriangle();  // Draw triangles (filled)

  testdrawchar();  // Draw characters of the default font

  testdrawstyles();  // Draw 'stylized' characters

  testscrolltext();  // Draw scrolling text

  testdrawbitmap();  // Draw a small bitmap image

  // Invert and restore display, pausing in-between
  display.invertDisplay(true);
  delay(1000);
  display.invertDisplay(false);
  delay(1000);

  testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT);  // Animate bitmaps

}

void loop() {  
  int temp_adc_val;
  float temp_val;
  temp_adc_val = analogRead(lm35_pin);	/* Read Temperature */
  temp_val = (temp_adc_val * 3.00/10);	/* Convert adc value to equivalent voltage */
  //temp_val = (temp_val/10);	/* LM35 gives output of 10mv/°C */
  Serial.print("Temperature = ");
  Serial.print(temp_val);
  Serial.println(" Degree Celsius");

  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);  // Draw white text
  display.setTextSize(2);               // Normal 1:1 pixel scale
  display.setCursor(0, 0);              // Start at top-left corner
  display.println(F("Temperature"));

  display.setTextSize(3);               // Normal 1:1 pixel scale
  //display.setCursor(0, 8);              // Start at top-left corner
  display.print(temp_val);
  
  display.setTextSize(1);               // Normal 1:1 pixel scale
  //display.setCursor(0, 32);              // Start at top-left corner
  display.cp437(true);
  display.write(248);//167
  display.setTextSize(3);
  display.print("C");
  display.display();                    // Important

  delay(2000);  
}

void printDirectory(File dir, int numTabs) {
  while (true) {
    File entry = dir.openNextFile();
    if (!entry) {
      // no more files
      break;
    }
    for (uint8_t i = 0; i < numTabs; i++) {
      Serial.print('\t');
      display.print('\t');
    }
    Serial.print(entry.name());
    display.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      display.println("/");
      printDirectory(entry, numTabs + 1);
    } else {
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
      display.print("\t\t");
      display.println(entry.size(), DEC);
    }
    entry.close();
  }
}

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0