arduino使用oled代码_<精彩开源项目分享>基于Arduino和OLED显示屏实现《生命游戏》中的微型细胞自动机...

项目概述

该项目使用I2C 128×64 OLED显示一个由Arduino Nano驱动的微型细胞自动机。

器件和材料

  • 半寸面包试验板 2块

09bd9cfda1b4d90978027b049227ab83.png
  • Arduino UNO开发板 1块

599c0acf0833210e6722a58721faff6a.png
  • 0.96寸 I2C OLED显示屏(128X64) 1块

71df17574d95aac543e6ed44a514ffa7.png
  • 跳线 4根

dc50261b5802b529a0d985f58b83e073.png

完成本项目的前提

在本教程中,我将假设您知道Arduino 是什么,并且知道如何使用IDE和上传简单的示例程序。还要懂一点编程,最好是C语言编程。

让我们开始吧!

项目背景

什么是细胞自动机?我将解释一种细胞自动机,这是约翰·康威的《生命游戏》。它是一个网格或单元格,每个单元格都有真或假/开或关/活或死两种状态。这些细胞由2个简单的规则控制:

规则1:一个死亡的细胞被恰好3个活着的细胞包围,就会诞生

规则2:一个活着的细胞如果有3个或2个活着的细胞,它就会继续活着,否则它就死了

很简单的,是吧?如果你想了解更多的信息,请在百度上搜索的”生命游戏”或”细胞自动机”。

以下解释来源于网络

细胞自动机(cellular automata)是为模拟包括自组织结构在内的复杂现象提供的一个强有力的方法,也称为元胞自动机(Cellular Automaton)。细胞自动机模型的基本思想是:自然界里许多复杂结构和过程,归根到底只是由大量基本组成单元的简单相互作用所引起。细胞自动机主要研究由小的计算机或部件,按邻域连接方式连接成较大的、并行工作的计算机或部件的理论模型。它分为固定值型、周期型、混沌型以及复杂型。

电路

将Arduino和OLED显示屏插到面包板上,并开始有跳线连接它们。

Arduino---OLED连接关系

  • 3.3v ———— VCC (注意你的OLED显示屏电压要求)
  • GND ———– GND
  • A4 ————– SDA
  • A5 ————– SCL

然后我将两个面包板背靠背地连接在一起,创建了一个小电视的造型

12286ae35f8947b203363dfc345630ec.png

2b6d815d80d1956124b17ef07019b3f6.png

程序设计示例

为了方便(并使之成为可能)使用OLED显示器,我们将使用Adafruit的两个库。如果您不知道如何添加库,请先阅读我专栏里的相关文章。

库1:Adafruit GFX库,用于处理OLED上显示的所有图形和文本https://github.com/adafruit/Adafruit-GFX-Library

库2:Adafruit SSD1306库,基本上是我们OLED的驱动程序。此库仅适用于OLED SSD1306 128×32和128×64:https://github.com/adafruit/Adafruit_SSD1306

完整的源代码如下:

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


#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

//set to 1 if the previous screen was the same as the current one
int sameScreen;

//Current grid
uint8_t grid[20][12];

//The new grid is used so that 'grid' is not compromised
uint8_t newgrid[20][12];


void setup()   {                

  // Serial.begin(9600); //use only for debugging purposes

  //Setting up the display pay attention to the address. Yours might be different
 
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //initialize with the I2C addr 0x3C (128x64)
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
 
  sameScreen=0;
}

void loop() {
 
    //Displaying a simple splash screen    

	display.clearDisplay();
	display.setTextSize(2);
	display.setTextColor(WHITE);
	display.setCursor(25,5);
	display.println(F("Arduino"));
	display.setCursor(20,25);
	display.println(F("Cellular"));        
	display.setCursor(20,45);
	display.println(F("Automata"));
	display.display();
	delay(2500);

	//Initialize CA
	display.setTextSize(2);
	display.clearDisplay();
	initGrid();
	drawGrid();
	delay(2000);
 
	//Compute 100 generations (or cycles) or less if screen remains static
	for (int gen=0;gen<100;gen++)
	{

	   computeCA();
		if (sameScreen==1){
		  gen=100;
		  sameScreen=0;
		}
	   drawGrid();
	   delay(250);
	}
 
}

//Draws the grid on the display
void drawGrid(void) {

  for (int16_t x=1; x<19;x++) {
    // alternate colors
 
    for (int16_t y=1; y<11;y++) {
      // alternate colors
        uint8_t color = grid[x][y];
        display.fillRect(6*x, 6*y, 6, 6, color);
       // Serial.print(color);
    }
    //Serial.println('n');
  }
  display.display();
}

//Initialize Grid
void initGrid(void){
  for (int16_t x=0; x<20;x++) {
    // alternate colors
 
    for (int16_t y=0; y<12;y++) {
      // alternate colors
        uint8_t color = random(2);
        if (x==0 || x==19 || y==0 || y==11){
          grid[x][y]=0;
        }
        else{
          if (color==1)
            grid[x][y]=1;
          else 
            grid[x][y]=0;
        }
    }
 
  }
}

//Compute the CA. Basically everything related to CA starts here
void computeCA(){
  for (int16_t x=1; x<19;x++) {
    // alternate colors
 
    for (int16_t y=1; y<11;y++) {
      // alternate colors
        int neighbors = getNumberOfNeighbors(x,y);
        if (grid[x][y]==1 && (neighbors == 2 || neighbors == 3 ))
        {
          newgrid[x][y]=1;
        }
        else if (grid[x][y]==1)  newgrid[x][y]=0;
        if (grid[x][y]==0 && (neighbors==3))
        {
          newgrid[x][y]=1;
        }
        else if (grid[x][y]==0) newgrid[x][y]=0;
    }
 
  }

  if (isSameScreen()) sameScreen=1;
 
  for (int16_t x=1; x<19;x++) {
    // alternate colors
 
    for (int16_t y=1; y<11;y++) {
      grid[x][y]=newgrid[x][y];
    }
  }
}

//check the Moore neighborhood
int getNumberOfNeighbors(int x, int y){
 // Serial.println(grid[x-1][y]+grid[x-1][y-1]+grid[x][y-1]+grid[x+1][y-1]+grid[x+1][y]+grid[x+1][y+1]+grid[x][y+1]+grid[x-1][y+1]);
  return grid[x-1][y]+grid[x-1][y-1]+grid[x][y-1]+grid[x+1][y-1]+grid[x+1][y]+grid[x+1][y+1]+grid[x][y+1]+grid[x-1][y+1];
}

//Checks if the new screen is exactly like the previous one
bool isSameScreen(){
  for (int16_t x=1; x<20;x++) {
    // alternate colors
 
    for (int16_t y=1; y<11;y++) {
      if(grid[x][y]!=newgrid[x][y]) return false;
    }
  }
  return true;
}

一些代码解释

在第51行代码中,

display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //initialize with the I2C addr 0x3C (128x64)

0X3C这个地址可以不同的OLED显示屏会有不同,买的时候可以问一下卖家默认的器件地址是多少,避免折腾。

让它跑起来吧

运行效果看下面的视频:

显示的水平线是OLED和摄像头刷新速率不一致的结果。

知乎视频​www.zhihu.com

如果你在代码或其他方面需要帮助,请在下面的评论区给我留言,感谢观看!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来为您提供一个 Arduino 使用 OLED 显示屏显示温湿度的代码。以下是示例代码: ``` #include &lt;Wire.h&gt; #include &lt;Adafruit_Sensor.h&gt; #include &lt;Adafruit_BME280.h&gt; #include &lt;Adafruit_GFX.h&gt; #include &lt;Adafruit_SSD1306.h&gt; #define OLED_RESET 4 Adafruit_SSD1306 display(OLED_RESET); Adafruit_BME280 bme; void setup() { Serial.begin(9600); if (!bme.begin(0x76)) { Serial.println("Could not find a valid BME280 sensor, check wiring!"); while (1); } if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); for (;;); } display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); display.println("Temperature & Humidity"); display.display(); } void loop() { display.clearDisplay(); display.setCursor(0,0); display.println("Temperature & Humidity"); display.setCursor(0,12); display.println("Temp: " + String(bme.readTemperature()) + " C"); display.setCursor(0,24); display.println("Humidity: " + String(bme.readHumidity()) + " %"); display.display(); delay(2000); } ``` 在这个代码,我们使用了 BME280 温湿度传感器来获取温度和湿度值。然后,我们使用 Adafruit_SSD1306 OLED 显示屏将这些值显示出来。代码的 `delay(2000)` 意味着我们每隔两秒更新一次显示屏。您需要先安装 Adafruit_Sensor、Adafruit_BME280、Adafruit_GFX 和 Adafruit_SSD1306 库才能成功编译和上传代码。 希望这可以帮助您和孩子一起做出一个显示温湿度的 OLED 屏桌面摆件!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值