ELM327とArduinoとLCD2004でOBDデータ表示

はじめに ELM327とArduinoとLCD2004で車両情報を表示してみました。 ELM327ではTrqueやCar Scannerなどのアプリで色々な車両情報は見れますが、だいたい見る項目は決まってきましたので作ってみました。 アプリより表示のレスポンスが向上しました。 「Arduino ELM327」などでググると、以下のELMduinoのような便利なライブラリも見つかりましたが、今回は使っていません。 PowerBroker2/ELMduino: Arduino OBD-II Bluetooth Scanner Interface Library for Car Hacking Projects 使ったもの ELM327 v1.5 Arduino UNO R2 Arduino Pro mini互換品 ATMega328,16MHz,5V LCD2004とI2Cアダプタ こちらと同じもの → Arduino I2C LCD2004 HelloWorld | atooshi-note ELM327殻割り 基板は3段構成になっていて一番上の青い基板はBluetooth Module(BTM)です。 BTMのチップ印字消されていますが、いろいろググってみるとHC-05のコンパチ?っぽそうです。 モジュールは3.3Vで駆動されていますが、typは3.6~6Vらしいですね。 RT,TX,3.3V,GND,5Vは以下の位置関係のようです。 参考 アナログタコメータをつくる(1) OBD2スキャナ ArduinoとELM327でOBD取得する 接続 ELM327はスマホで動作確認はできていますので、PCとシリアル通信してみます。 USB-TTLデバイスを用意して、以下のように接続します。 ELM327 USB-TTL 5V 5V GND GND TX RX RX TX 通常は定番のFTDIの石を使うと思いますが、持っていないのでCH32V003用に持っているWCH-LinkEを使いました。 COMポートとして認識されるデバイスなら通信できそうです。 Arduino UNO R2のUSB-シリアル変換部分も同じように使うことができます。その場合、以下のように接続します。 ArduinoのTX(pin1)はUSB-シリアル変換部分のRXに、RX(pin0)はTXに繋がっているので、クロス接続にはしません。 以下↓にも記載しています。 NCP-HG100 を 楽天モバイル Band3 に固定する | atooshi-note ...

2025/02/08 · Last updated on 2025/03/28 · 8 min · 1582 words

ch32v003fun CH32V003F4P6 シリアル通信

はじめに シリアル通信を試しました 注意点 SWIOだけではシリアル通信できません。 WCH-LinkEのRXとCH32V003F4P6のUTX(pin2,PD5)を接続する必要があります。 接続 3.3V GND SWIO(PD1) TX(PD5)の4本です。 プログラム サンプルがほぼそのままで動作しました。楽〜 C:\Users\USERNAME\Downloads\ch32v003fun\examples\uart_tx_dma\uart_tx_dma.c ch32v003funをWindowsに構築しCH32V003F4P6でLチカ | atooshi-noteでch32v003funをダウンロードした場所と同じです。 接続してポートを認識しており(COM7でした)、teratermで通信を確認しました。 /* * This example uses DMA for the UART to transfer the "Hello World!\r\n" string * once per second. Connect a UART Rx pin to D5, flash the example, setup your * uart for 115200n1 and the messages should appear シリアル通信のチェック */ #include "ch32v003fun.h" // Set UART baud rate here #define UART_BR 115200 // LED on D6 (nanoCH32V003 board) // #define LED_PIN 6 #define LED_PIN 4 // ch32v003f4p6のdevelopmetboard // DMA transfer completion interrupt. It will fire when the DMA transfer is // complete. We use it just to blink the LED __attribute__((interrupt)) __attribute__((section(".srodata"))) void DMA1_Channel4_IRQHandler(void) { // Clear flag DMA1->INTFCR |= DMA_CTCIF4; // Blink LED GPIOD->OUTDR ^= 1<<LED_PIN; } static void led_setup(void) { RCC->APB2PCENR = RCC_APB2Periph_GPIOD; GPIOD->CFGLR = ((GPIO_CNF_IN_PUPD)<<(4*1)) | // Keep SWIO enabled. (GPIO_Speed_2MHz | GPIO_CNF_OUT_PP)<<(4*LED_PIN); // LED ON GPIOD->BSHR = 1<<LED_PIN; } static void uart_setup(void) { // Enable UART and GPIOD RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_USART1; // Push-Pull, 10MHz Output on D5, with AutoFunction GPIOD->CFGLR = (GPIOD->CFGLR & ~(0xF<<(4*5))) | ((GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*5)); // Setup UART for Tx 8n1 USART1->CTLR1 = USART_WordLength_8b | USART_Parity_No | USART_Mode_Tx; USART1->CTLR2 = USART_StopBits_1; // Enable Tx DMA event USART1->CTLR3 = USART_DMAReq_Tx; // Set baud rate and enable UART USART1->BRR = ((FUNCONF_SYSTEM_CORE_CLOCK) + (UART_BR)/2) / (UART_BR); USART1->CTLR1 |= CTLR1_UE_Set; } static void dma_uart_setup(void) { // Enable DMA peripheral RCC->AHBPCENR = RCC_AHBPeriph_SRAM | RCC_AHBPeriph_DMA1; // Disable channel just in case there is a transfer in progress DMA1_Channel4->CFGR &= ~DMA_CFGR1_EN; // USART1 TX uses DMA channel 4 DMA1_Channel4->PADDR = (uint32_t)&USART1->DATAR; // MEM2MEM: 0 (memory to peripheral) // PL: 0 (low priority since UART is a relatively slow peripheral) // MSIZE/PSIZE: 0 (8-bit) // MINC: 1 (increase memory address) // CIRC: 0 (one shot) // DIR: 1 (read from memory) // TEIE: 0 (no tx error interrupt) // HTIE: 0 (no half tx interrupt) // TCIE: 1 (transmission complete interrupt enable) // EN: 0 (do not enable DMA yet) DMA1_Channel4->CFGR = DMA_CFGR1_MINC | DMA_CFGR1_DIR | DMA_CFGR1_TCIE; // Enable channel 4 interrupts NVIC_EnableIRQ(DMA1_Channel4_IRQn); } static void dma_uart_tx(const void *data, uint32_t len) { // Disable DMA channel (just in case a transfer is pending) DMA1_Channel4->CFGR &= ~DMA_CFGR1_EN; // Set transfer length and source address DMA1_Channel4->CNTR = len; DMA1_Channel4->MADDR = (uint32_t)data; // Enable DMA channel to start the transfer DMA1_Channel4->CFGR |= DMA_CFGR1_EN; } int main(void) { static const char message[] = "Hello World!!!\r\n"; SystemInit(); led_setup(); uart_setup(); dma_uart_setup(); while (1) { dma_uart_tx(message, sizeof(message) - 1); Delay_Ms(1000); } } 参考 CH32V003をArduinoで使う: DJ HIGO オフィシャルブログ ...

2025/01/16 · Last updated on 2025/03/14 · 2 min · 421 words

ch32v003funをWindowsに構築しCH32V003F4P6でLチカ

はじめに ch32v003funの環境をWindowsに構築したメモです。 Installation · cnlohr/ch32fun Wikiの通りにやれば良いのですが、自分のまとめをしました。 環境 Windows10 CH32V003F4P6 Development board 詳細はアリエクで買ったCH32V003F4P6 Development board | atooshi-noteに記載 WCH-LinkE version 2.15 構築 githubからch32v003funを好きなフォルダにダウンロードします。 cnlohr/ch32fun: Open source minimal stack for the ch32 line of WCH processors, including the ch32v003, a 10¢ 48 MHz RISC-V Microcontroller - as well as many other chips within the ch32v/x line. 私は、C:\Users\USERNAME\Downloads\ch32v003funにgit cloneしました。 gccインストール Prebuilt GNU toolchain for RISC-Vから、risc-v-gcc10.1.0.exe (22 MB) をダウンロード、イントールします。 インストール先:C:\SysGCC The minichlink.exe file is already ready to go in the minichlink folder. ...

2025/01/06 · Last updated on 2025/03/14 · 3 min · 445 words

16bitを上位8bit,下位8bitに分ける,2つの8bitを16bitに結合する

題名のまんまですが、16bitを上位8bit、下位8bitに分ける方法と、逆に、2つの8bitを16bitに結合する方法についてのメモです(^^) 用途 シリアル通信(UART)の送受信単位は1文字=1byte(8bit)なので、マイコンで16bitで定義した値を上位8bit、下位8bitに分けて送信したい。(PC側で16bitに結合して表示) 1byte(8bit)で受信したデータをマイコンで16bitに結合して、値を得たい。 16bitを上位8bit、下位8bitにわける やっていることは以下です。 上位8bitを抽出 : 右に8bitシフト(下位8bitにシフト) 下位8bitを抽出 : 0x00FFと”&”(アンド)をとる // 2byte(16bit)を上位8bit,下位8bitにわける unsigned short a,bH,bL // 2byte(16bit)で宣言 // bH : aの上位8bitを入れる // bL : aの下位8bitを入れる a = 0x4F1A; // 適当な値(2byte) // aの上位8bitをbHに入れる bH = a >> 8; // 右に8bitシフト(下位8bitにシフト) // bH = 0x004F // aの下位8bitをbLにいれる bL = a & 0x00FF; // 0x00FFと&をとる // bL = 0x001A 上位8bitの抽出 a = 0x4F1Aのように、適当な値を16進数で定義しました。 2進数で表現すると、a = 0b 0100 1111 0001 1010 (0bは2進数の意味) aの上位8bitは右に8bitビットシフトすることで得ます。 ”»”は右にビットシフトする演算子です。 a = 0b 0100 1111 0001 1010 ↓↓ bH = a » 8 ↓↓ ...

2020/03/15 · Last updated on 2021/10/19 · 2 min · 237 words

アスキーコード変換 シリアル通信

以下の記事で紹介しているTiのマイコンはC言語で書かれています。 というわけでC言語の勉強もしているわけですが、せっかくなのでわかった内容も確認のための書いてみようと思います。 今回はPCとシリアル通信する際に、アスキーコード変換が必要だったので、そのことについて記載します(^^) これはCに限った話ではないですが、Cの勉強の一環として。。。 環境 Windows10 Pro バージョン1809 64bit Tera Term v4.105(19/12/07) やったこと Tera TermにCPU温度を表示させる際に、アスキーコード変換した。 ことの発端 TiのこのマイコンにはADコンバータの一つが内部の温度センサーにつながっていて、CPUのジャンクション温度を測定することができます。 このCPU温度をPCのシリアルモニター(Tera Term)に表示させようとしたところ、アスキーコード変換されて、よくわからない文字になってしまった。ということがきっかけです。 プログラム // 宣言 unsigned short DEG; // shortは16bit 温度は正の値しか無いとしてunsignedとしています unsigned short DEGTen; // DEGの10の位 整数型で定義 unsigned short DEGone; // DEGの1の位 unsigned short DEGTenASCII; // DEGの10の位をアスキーコード変換した値 unsigned short DEGoneASCII; // DEGの1の位をアスキーコード変換した値 DEG = 47; // DEGはCPU温度で仮に47℃とします // 各桁の値の抽出 DEGTen = DEG / 10; DEGone = DEG % 10; // アスキーコード変換 DEGTenASCII = DEGTen + 0x30; // これをTera Termでみると「4」と表示される DEGoneASCII = DEGone + 0x30; // これをTera Termでみると「7」と表示される 説明 Tera Termにはアスキーコード表の文字が表示されます。 例えば、CPU温度47℃とすると、47は10進数なので、アスキーコード表だと、「/」という文字に相当します。 ですので、マイコンから数値の47(10進数)をシリアル送信しても、Tera Termには「/」が表示されます。でも、「/」と表示されていては直感的に温度がわからず不便なので、Tera Termでも「47」と表示されるようにします。つまり、「47」という文字に相当する数値をマイコンから送信します。 シリアル通信は、1文字ずつ(1byte=8bitずつ)送信のため、「4」と「7」という2文字を分けて送信する必要があります。ですので、47を10の位と1の位に分解します。 10の位の抽出 まず、10の位を抽出します。 10の位は47を10で割ります。 割った値はDEGTenとしてunsigned short(整数型)で定義します。 47 / 10=4.7ですが、整数型で定義しているので、小数は扱えません。すると、小数以下は切り捨てられます。ですので「4」のみが残ります。 これで10の位が抽出できました。 DEGTen = DEG / 10; unsignedで定義しているのは、温度は正の値しか無いとしているからです。shortで定義しても問題ありません。また、温度は常識的に100℃程度までと考えると、short=16bit=216=-32768 ~ 32767(unsigned shortなら0 ~ 65535)の値を扱えるので、範囲内で全然問題ありませんし、char=8bit=28=-128~127(unsigned charなら0~255)でも良いです。 ...

2020/02/29 · Last updated on 2020/03/07 · 2 min · 386 words