物料

1. Esp32开发板(带蓝牙)--19元

2. 1.6寸 130*130 半反半透屏 SPI接口(强烈建议半反半透屏,整体效果均衡,阳光下效果也不错)   ---- 15元, 现在涨到20+了

3. 万能 PCB板,排针,排针座(如果屏幕直插,注意排针和排针座高度,或者直接用排线),蜂鸣器(可选) ---算10元吧

4. 蓝牙OBD(建议选拔掉壳后,薄薄的哪种,不影响把盖子盖回去)  ---10十~40元,基本最便宜的都能满足需求

连线也极其简单,就是屏幕,另外有一个按键,这个按键完全可以不要

/*******************************************************************************Start of Arduino_GFX settingArduino_GFX try to find the settings depends on selected board in Arduino IDEOr you can define the display dev kit not in the board listDefalult pin list for non display dev kit:Arduino Nano, Micro and more: TFT_CS:  9, TFT_DC:  8, TFT_RST:  7, TFT_BL:  6ESP32 various dev board     : TFT_CS:  5, TFT_DC: 27, TFT_RST: 33, TFT_BL: 22ESP8266 various dev board   : TFT_CS: 15, TFT_DC:  4, TFT_RST:  2, TFT_BL:  5Raspberry Pi Pico dev board : TFT_CS: 17, TFT_DC: 27, TFT_RST: 26, TFT_BL: 28RTL872x various dev board   : TFT_CS: 18, TFT_DC: 17, TFT_RST:  2, TFT_BL: 23Seeeduino XIAO dev board    : TFT_CS:  3, TFT_DC:  2, TFT_RST:  1, TFT_BL:  0Teensy 4.1 dev board        : TFT_CS: 39, TFT_DC: 41, TFT_RST: 40, TFT_BL: 22******************************************************************************/
#include <Arduino_GFX_Library.h>
#include "FreeMonoBold14pt7b.h"
#include "FreeMonoBold36pt7b.h"#include "BluetoothSerial.h"
#include "ELMduino.h"
#include "time.h"
#include "esp_system.h"uint8_t address[6]  = {0x34, 0x90, 0x1b, 0x20, 0xa6, 0x92};
String name = "OBDII";
BluetoothSerial SerialBT;
#define ELM_PORT SerialBT
#define DEBUG_PORT Serial
#define MAX_SPEED 512
#define INVALID_SPEED -1
#define BUTTON_PIN 32
#define BUZZER_VCC 18
#define BUZZER_GND 19struct Button {const uint8_t PIN;uint32_t numberKeyPresses;unsigned long lastInterrupt;bool pressed;
};Arduino_DataBus *bus = new Arduino_ESP32SPI(4 /* DC */, 15 /* CS */, 17 /* SCK */, 16 /* MOSI */, -1 /* MISO */, VSPI /* spi_num */);
Arduino_GFX *gfx = new Arduino_SSD1283A(bus, 2 /* RST */, 2 /* rotation */);
Button button1 = {BUTTON_PIN, 0, 0, false};
ELM327 myELM327;
int32_t oriSpeed = 0;
int32_t fixSpeed = 0;
int32_t lastOriSpeed = 0;unsigned long bootTime = 0 ;
unsigned long runTime = 0;
bool isBuzzerEnable = true;
bool lastStatusOk = false;void buzzerOn() {digitalWrite(BUZZER_VCC, HIGH);
}void buzzerOff() {digitalWrite(BUZZER_VCC, LOW);
}void buzzerTime(uint8_t t) {if (!isBuzzerEnable) {return;}for (uint8_t i = 0 ; i < t; i++) {buzzerOn();delay(200 + i * 30);buzzerOff();delay(50 + i * 10);}
}//void measure(char *s, int16_t x, int16_t y) {
//
//  int16_t x1, y1;
//  uint16_t w, h;
//  gfx->getTextBounds(s, x, y, &x1, &y1, &w, &h);
//  //  gfx->fillRect(x1, y1, w, h, BLACK);
//  Serial.printf("x1 = %d , y1 = %d, w = %d, h = %d\n", x1, y1, w, h);
//}void initBuzzer() {pinMode(BUZZER_VCC, OUTPUT);  // Buzzer VCCpinMode(BUZZER_GND, OUTPUT);  // Buzzer GNDdigitalWrite(BUZZER_VCC, HIGH);digitalWrite(BUZZER_GND, LOW);delay(50);digitalWrite(BUZZER_VCC, LOW);
}void initTFT() {gfx->begin();gfx->fillScreen(BLACK);pinMode(TFT_BL, OUTPUT);digitalWrite(TFT_BL, HIGH);gfx->setFont(&FreeMonoBold14pt7b);gfx->fillScreen(BLACK);
}void showRuntime() {uint16_t x = 1;uint16_t y = 20;gfx->setTextColor(YELLOW, BLACK);gfx->setCursor(x, y);gfx->setFont(&FreeMonoBold14pt7b);uint8_t h = runTime / 3600;uint8_t m = runTime / 60 % 60;uint8_t s = runTime % 60;gfx->printf("%02d:%02d:%02d", h, m, s);}void showFixSpeed(int32_t speed) {uint16_t x = 0;uint16_t y = 80;gfx->setTextColor(WHITE, BLACK);gfx->setCursor(x, y);gfx->setFont(&FreeMonoBold36pt7b);gfx->printf("%3d", speed);
}void showOriSpeed(int32_t speed) {uint16_t x = 0;uint16_t y = 120;gfx->setFont(&FreeMonoBold14pt7b);gfx->setTextColor(GREEN, BLACK);gfx->setCursor(1, 120);gfx->printf("%3d", speed);gfx->setTextColor(PINK, BLACK);gfx->setCursor(60, 120);gfx->printf("km/h");
}void initOBD() {int8_t retryCount = 0;gfx->setFont(&FreeMonoBold14pt7b);gfx->setCursor(0, 60);gfx->println("initOBD");DEBUG_PORT.begin(115200);//  SerialBT.setPin("1234");ELM_PORT.begin("ArduHUD", true);while (!ELM_PORT.connect(address)) {//  while (!ELM_PORT.connect("MI9")) {DEBUG_PORT.println("Couldn't connect to OBD scanner - 1");gfx->fillScreen(BLACK);gfx->setCursor(0, 60);gfx->printf("Connect\n   %d", ++retryCount);if (retryCount > 5) {gfx->fillScreen(BLACK);gfx->setCursor(0, 60);gfx->println("Restart");delay(2000);esp_restart();}}if (!myELM327.begin(ELM_PORT, true, 2000)) {DEBUG_PORT.println("Couldn't connect to OBD scanner - 2");gfx->fillScreen(BLACK);gfx->setCursor(0, 60);gfx->println("No connection");}DEBUG_PORT.println("Connected to ELM327");
}void printSpeed() {static uint8_t noDataCount = 0;oriSpeed = myELM327.kph();if (myELM327.status != ELM_SUCCESS) {noDataCount++;if (noDataCount >= 3) {myELM327.printError();gfx->fillScreen(BLACK);gfx->setCursor(0, 60);gfx->println("no data");lastStatusOk = false;}} else {if (oriSpeed > MAX_SPEED) {oriSpeed = INVALID_SPEED;}fixSpeed = (int)(oriSpeed * 1.05 );if (!lastStatusOk) {gfx->fillScreen(BLACK);}showFixSpeed(fixSpeed);showOriSpeed(oriSpeed);lastStatusOk  = true;DEBUG_PORT.printf("oriSpeed = %d , lastOriSpeed = %d\n", oriSpeed, lastOriSpeed);if (oriSpeed > 120 && lastOriSpeed <= 120) {buzzerTime(3);} else if ( oriSpeed > 100 && lastOriSpeed <= 100) {buzzerTime(2);} else if (oriSpeed > 80 && lastOriSpeed <= 80) {buzzerTime(1);}lastOriSpeed = oriSpeed;noDataCount = 0;}
}void IRAM_ATTR isr() {unsigned long curT = millis();DEBUG_PORT.printf("isr, time : %d, lastTime : %d \n", curT, button1.lastInterrupt);if (curT - button1.lastInterrupt < 10) {DEBUG_PORT.printf("skip isr, time : %d \n", curT - button1.lastInterrupt);return;}button1.lastInterrupt = curT;button1.numberKeyPresses += 1;isBuzzerEnable = !isBuzzerEnable;button1.pressed = true;
}void setup(void)
{Serial.begin(115200);bootTime = millis();initBuzzer();initTFT();initOBD();// init ButtonpinMode(button1.PIN, INPUT_PULLUP);attachInterrupt(button1.PIN, isr, RISING);//  attachInterrupt(button1.PIN, isr, FALLING);
}void loop()
{static long lastRefresh = 0;if (millis() - lastRefresh > 500) {lastRefresh = millis();runTime =  (millis() - bootTime) / 1000;showRuntime();printSpeed();}if (button1.pressed) {button1.pressed = false;gfx->fillScreen(BLACK);gfx->setCursor(0, 60);gfx->println(isBuzzerEnable ? "Enable Buzzer" : "Disable Buzzer");delay(1000);}
}

基于esp32 Arduino自制蓝牙HUD显示相关推荐

  1. 基于esp32的手机蓝牙收发调试器

    一,实验准备 开始之前,先吹一波ESP32,乐鑫YYDS!ESP32包含WIFI模块和蓝牙4.0模块,双核CPU工作频率为80-240Mhz,其大致功能如下图所示: 外设接口 • 34 个 GPIO ...

  2. 基于ESP32的智能蓝牙窗帘(模拟)

    环境 ESP32: Arduino APP : HbuilderX 外围器件:BH1750(GY-302) 硬件思路: (1)功能:划分为手动和自动模式,在手动模式下,可手动控制窗帘的打开和关闭:在自 ...

  3. ESP32与APP通信--基于MicroPythone的BLE蓝牙篇

    基于ESP32的低功耗蓝牙程序 1,编译环境搭建:基于MicroPython的ESP32环境搭建 2,代码直接复制 """ The MIT License (MIT) C ...

  4. 基于ESP32的蓝牙小手柄 | 附Arduino源码

    基于ESP32的蓝牙小手柄 | 附Arduino源码 在B站看到了UP主皇工小毒仔的的视频感觉很有意思,可以拿来打原神,于是把他复现了出来由于UP主并没有开源代码,于是我把我的代码和UP主开源的网址一 ...

  5. arduino nano 蓝牙_用Arduino玩转掌控板(ESP32):ESP32概述与Arduino软件准备

    前言 近年来,掌控板(英文名:mPython)在创客教育中应用越来越广泛.掌控板集成了 ESP32 高性能双核芯片,具备 WiFi 和蓝牙连接功能,同时在板子上又配置了丰富的传感器,最重要的是它是专门 ...

  6. esp32摄像显示时间_科普系列 || 第一弹~基于ESP32的WiFi连接

    点击蓝字关注 东南大学电子科协公众号- 号外号外!     还因为宅在家中无所事事吗,科协现在为了同学们帮助学习单片机和后面准备竞赛,电子科协决定推出一个系列文章,帮助大家了解常用的一些总线和一些通讯 ...

  7. 基于ESP32的蓝牙翻页器设计(论文附调试成功代码!!)

    基于ESP32的蓝牙翻页器设计 目录 基于ESP32的蓝牙翻页器设计 1 摘要 1 1.绪论 2 1.1认识蓝牙 2 1.2研究思路 3 2.软硬件设计 3 2.1中央处理模块------ESP32 ...

  8. 基于ESP32的蓝牙刷屏器自动点击器的制作

    ESP32模块的选型: 这里是利用蓝牙连接手机来做点击器或刷屏器,ESP8266只有WIFI而ESP32有WIFI和蓝牙,所以选择ESP32模块. ESP32模块可以选择ESP32-NodeMCU: ...

  9. arduino nano 蓝牙_掌控板IO接口编程入门 | 用Arduino玩转掌控板(ESP32)系列

    众所周知,掌控板在创客教育中用的非常广泛,它是一块基于 ESP32 的学习开发板.大家对掌控板编程,用的比较多的都是图形化编程的方式,比如 mPython.Mind+ 等.但是,既然掌控板是基于 ES ...

最新文章

  1. AI一周热闻:GitHub免费开放无限私有库;苹果市值蒸发超450亿美元;小米入股TCL...
  2. P6805-[CEOI2020]春季大扫除【贪心,树链剖分,线段树】
  3. vue变量传值_Vue各类组件之间传值的实现方式
  4. 南京财经大学计算机专业读研,计算机考研报录比比较的院校:南京财经大学
  5. SDUT 1291数据结构上机测试4.1:二叉树的遍历与应用1
  6. lucene造成磁盘空间不足的问题
  7. JSK-T1011 反向输出一个三位数【入门】
  8. pycharm python脚本如何调试_Pycharm调试程序技巧小结
  9. python提取国家名称缩写_如何从python中的国家缩写中获取国家名称,并混合使用alpha_2和alpha_3 ccodes...
  10. koa教程--busboy模块
  11. Direcshow中视频捕捉和参数设置报告
  12. 腾讯QQ关闭所有的热键,防止冲突
  13. gif动图怎么制作更简单,手把手教你在线gif制作
  14. 国内外RTI产品调查情况
  15. SQL“除非另外还指定了 TOP、OFFSET 或 FOR XML,否则,ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效“ 解决方法
  16. 【事件图谱】事件抽取与事件关系抽取
  17. Android Framework启动流程
  18. 大数据中台架构以及建设全流程一(Paas层设计)
  19. 你知道的企业文化理念有哪些?
  20. 苹果订阅的升级、降级、同级转换

热门文章

  1. Retrofit2 工作原理解析(一)
  2. windows 7 64位无法连接到HP5200LX打印机 (错误 0x0000007e)的解决方法
  3. 跳汰洗煤及跳汰机操作
  4. Observability
  5. 将flash中的代码复制到RAM中运行的方法
  6. Winform控件开发(15)——contextMenuStrip(史上最全)
  7. 教师在初中数学课堂该如何有效提问(内有示例)
  8. 西邮Linux兴趣小组2020纳新试题
  9. keras电影评论分类
  10. 易语言与服务器即时通讯,求易语言简单即时通讯