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