[PYTHON] Create a car meter with raspberry pi

This is a continuation of the previous Power Management. This time, I made a meter display side using electron. At this level, it was easy because the thing made with windows worked almost as it was. If you want to see all the code, click here pi_meter

pi_meter.gif

A little explanation

code

electron side

index.html


<!DOCTYPE html>
<html>
<header>
	<link rel="stylesheet" type="text/css" href="./style.css">
</header>
<head>
	<meta charset="UTF-8">
	<title>pi_meter</title>
</head>
<body>
	<div class="wrapper">
		<div class="analog" >
			<div class="analog_li" id="a_wtmp">
				<img src="./img/a_water_t.png " alt="panel" />
			</div>
			<div class="analog_li" id="a_otmp">
				<img n src="./img/a_oil_t.png " alt="panel" />
			</div>
			<div class="analog_li" id="a_opls">
				<img  src="./img/a_oil_p.png " alt="panel" />
			</div>
		</div>
		<div class="degital">
			<div class="d_li" id="d_wtmp">
				<img class="d_p"  src="./img/d_water_t.png " alt="panel" />
			</div>
			<div class="d_li" id="d_otmp">
				<img class="d_p"  src="./img/d_oil_t.png " alt="panel" />
			</div>
			<div class="d_li" id="d_opls">
				<img class="d_p"  src="./img/d_oil_p.png " alt="panel" />
			</div>
		</div>
		<div class="analog_bar">
			<div class="b_bar_li" id="b_wtmp">
				<img class="b_a" src="./img/a_bar.png " id="im_wtmp"  alt="meter_bar" />
			</div>
			<div class="b_bar_li" id="b_otmp">
				<img class="b_a" src="./img/a_bar.png " alt="meter_bar" />
			</div>
			<div class="b_bar_li" id="b_opls">
				<img class="b_a" src="./img/a_bar.png " id="im_opls" alt="meter_bar" />
			</div>
		</div>
		<div class="digital_str">
			<div class="digital_str_li" id="str_wtmp">
			</div>
			<div class="digital_str_li" id="str_otmp">
			</div>
			<div class="digital_str_li" id="str_opls">
			</div>
		</div>
	</div>
</body>
<script type="text/javascript" src="script.js"></script>
</html>

main.js


'use strict';

const electron = require("electron");
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
let mainWindow;

app.on('window-all-closed', function() {
  if (process.platform != 'darwin') {
    app.quit();
  }
});

app.on('ready', function() {
  mainWindow = new BrowserWindow({
        frame: true,
        fullscreen: true,
  });
  mainWindow.loadURL('file://' + __dirname + '/index.html');
  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});

script.js


'use strict';


const remote = require('electron').remote;
//Get browser window
const browserWindow = remote.getCurrentWindow();
//Get screen size array[0]Is the width,[1]Is the vertical width
const win_size = browserWindow.getSize();

//Counter used at the opening
var counter=0;
//Maximum number of counters to use at the opening
var animaton_counter=100;//10msec * 200 = 2seconds
//Counter used in the moving opening of each meter
var counter1=0;
var counter2=0;
var counter3=0;
//Value to advance the counter used in the movement opening of each meter
var add_counter1 = 0; 
var add_counter2 = (win_size[0]/3)/animaton_counter; 
var add_counter3 = (win_size[0]/3*2)/animaton_counter; 

//Maximum value of counter = fixed point
var count_max1 = 0;
var count_max2 = (win_size[0]/3);
var count_max3 = (win_size[0]/3*2);

//Get each round meter background
var a_wtmp = document.getElementById("a_wtmp");
var a_otmp = document.getElementById("a_otmp");
var a_opls = document.getElementById("a_opls");

//Get each character meter background
var d_wtmp = document.getElementById("d_wtmp");
var d_otmp = document.getElementById("d_otmp");
var d_opls = document.getElementById("d_opls");

//Acquisition of character display for each character meter
var str_wtmp = document.getElementById("str_wtmp");
var str_otmp = document.getElementById("str_otmp");
var str_opls = document.getElementById("str_opls");

//Acquisition of needle image of each round meter
var bar_wtmp = document.getElementById("b_wtmp");
var bar_otmp = document.getElementById("b_otmp");
var bar_opls = document.getElementById("b_opls");

//Display angle of each meter needle
var rt_wtmp=0;
var rt_otmp=0;
var rt_opls=0;

//Variables for acquiring water temperature and variables for temporary storage
var tmp_wtmp1=0;
var tmp_wtmp2=0;

//Variables for obtaining oil temperature and variables for temporary storage
var tmp_otmp1=0;
var tmp_otmp2=0;

//Variables for acquiring hydraulic pressure and variables for temporary storage
var tmp_opls1=0;
var tmp_opls2=0;

//Wrap flag used in Opening
var turn_flg=0;

//Acquisition of data file for meter
var fs = require('fs');
var filepath = './meter_data.json';

//Window minimization
document.getElementById("im_opls").addEventListener("click", function (e) {
	browserWindow.minimize(); 
});

//End processing
document.getElementById("im_wtmp").addEventListener("click", function (e) {
	browserWindow.close();
}); 

//Movement of round meter
function mv_analog_p(){
	a_wtmp.style.left = 0+'px';
	a_wtmp.style.top= 0+'px';

	a_otmp.style.left = counter2+'px';
	a_otmp.style.top= 0+'px';

	a_opls.style.left = counter3+'px';
	a_opls.style.top= 0+'px';
}

//Moving the character meter
function mv_dgital_p(){
	d_wtmp.style.left = 0+'px';
	d_wtmp.style.top= (win_size[0]/3)+'px';
	
	d_otmp.style.left = counter2+'px';
	d_otmp.style.top= (win_size[0]/3)+'px';
 
	d_opls.style.left = counter3+'px';
	d_opls.style.top= (win_size[0]/3)+'px';
}

//Moving the display for the modifier
function mv_dgital_str(){
	str_wtmp.style.right = (counter3+(win_size[0]/12))+'px';
	str_wtmp.style.top= (win_size[0]/24*9)+'px';
	str_wtmp.style.zIndex = '4';
	str_wtmp.style.fontSize=(win_size[0]/8)+"px";

	str_otmp.style.right = (counter2+(win_size[0]/12))+'px';
	str_otmp.style.top= (win_size[0]/24*9)+'px';
	str_otmp.style.zIndex = '4';
	str_otmp.style.fontSize=(win_size[0]/8)+"px";

	str_opls.style.right = (win_size[0]/12)+'px';
	str_opls.style.top= (win_size[0]/24*9)+'px';
	str_opls.style.zIndex = '4';
	str_opls.style.fontSize=(win_size[0]/8)+"px";
}

//Movement of round meter needle
function mv_analog_bar(){
	bar_wtmp.style.left = 0+'px';
	bar_wtmp.style.top= 0+'px';
	bar_wtmp.style.zIndex = '5';
	bar_wtmp.style.webkitTransform = "rotate("+rt_wtmp+"deg)";

	bar_otmp.style.left = count_max2+'px';
	bar_otmp.style.top= 0+'px';
	bar_otmp.style.zIndex = '5';
	bar_otmp.style.webkitTransform = "rotate("+rt_otmp+"deg)";

	bar_opls.style.left = count_max3+'px';
	bar_opls.style.top= 0+'px';
	bar_opls.style.zIndex = '5';
	bar_opls.style.webkitTransform = "rotate("+rt_opls+"deg)";
}

//For drawing the opening
function draw_data(){
	bar_wtmp.style.webkitTransform = "rotate("+rt_wtmp+"deg)";
	document.getElementById("str_wtmp").innerHTML = (rt_wtmp/2.25).toFixed(0);
	bar_otmp.style.webkitTransform = "rotate("+rt_otmp+"deg)";
	document.getElementById("str_otmp").innerHTML = (rt_otmp/1.8).toFixed(0);
	bar_opls.style.webkitTransform = "rotate("+rt_opls+"deg)";
	document.getElementById("str_opls").innerHTML = (rt_opls/27).toFixed(1);
}

//Panel movement opening
function start_meter(){
	if(counter<animaton_counter){
		mv_analog_p();
		mv_dgital_p();
		counter2=counter2+add_counter2;
		counter3=counter3+add_counter3;
		counter++;
		setTimeout('start_meter()',10);
	}else{
		counter1=count_max1;
		counter2=count_max2;
		counter3=count_max3;
		mv_analog_p();
		mv_dgital_p();
		mv_dgital_str();
		mv_analog_bar();
		opening();
	}
}

//opening
function opening() {
	if( (rt_wtmp!=270) && (turn_flg==0) ){
		rt_wtmp+=2;
		rt_otmp+=2;
		rt_opls+=2;
		draw_data();
		setTimeout("opening()",10);
	}else if( (rt_wtmp==270) && (turn_flg==0)  ){
		turn_flg=1;
		setTimeout("opening()",200);
	}else if((rt_wtmp!=0) && (turn_flg==1)){
		rt_wtmp-=2;
		rt_otmp-=2;
		rt_opls-=2;
		draw_data();
		setTimeout("opening()",10);
	}else if ((rt_wtmp==0) && (turn_flg==1)){
		turn_flg=0;
		setTimeout("mainloop()",15);
	}
}

//Read data
function check_data() {
        try{
                var json_data = JSON.parse(fs.readFileSync(filepath, 'utf8'));
                tmp_wtmp1=parseInt(json_data["wtmp"]);
                tmp_otmp1=parseInt(json_data["otmp"]);
                tmp_opls1=parseInt(json_data["opls"]);
        }catch (err){
        }
}
//Test check_data()Instead of using it now
function test_data() {
	if(turn_flg==0){
		tmp_wtmp1++;
		tmp_otmp1++;
		tmp_opls1++;
	}else{
		tmp_wtmp1--;
		tmp_otmp1--;
		tmp_opls1--;
	}
	if(tmp_wtmp1==100){
		turn_flg=1;
	}else if(tmp_wtmp1==0){
		turn_flg=0;
	}
}

//Main loop
function mainloop(){
	check_data();
	if(tmp_wtmp1!=tmp_wtmp2){
		if(tmp_wtmp1 > tmp_wtmp2){
			tmp_wtmp2++;
		}else{
			tmp_wtmp2--;
		}
		rt_wtmp=tmp_wtmp2*2.25;
		bar_wtmp.style.webkitTransform = "rotate("+rt_wtmp+"deg)";
		document.getElementById("str_wtmp").innerHTML = tmp_wtmp2 ;
	}
		
	if(tmp_otmp1!=tmp_otmp2){
		if(tmp_otmp1 > tmp_otmp2){
			tmp_otmp2++;
		}else{
			tmp_otmp2--;
		}
		rt_otmp=tmp_otmp2*1.8;
		bar_otmp.style.webkitTransform = "rotate("+rt_otmp+"deg)";
		document.getElementById("str_otmp").innerHTML =tmp_otmp2;
	}

	if(tmp_opls1!=tmp_opls2){
		if(tmp_opls1 > tmp_opls2){
			tmp_opls2++;
		}else{
			tmp_opls2--;
		}
		rt_opls=tmp_opls2*2.7;
		bar_opls.style.webkitTransform = "rotate("+rt_opls+"deg)";
		document.getElementById("str_opls").innerHTML =(tmp_opls2/10).toFixed(1);
	}
	setTimeout("mainloop()",15);
}


window.onload = function(){
	start_meter();
}

The following is the previous difference.

arduino side

arduino.ino


#define WTMP_IN (A0) //water temp
#define OTMP_IN (A1) //oil temp 
#define OPLS_IN (A2) //oil press
#define B_LV_IN (A3) //battery level 

~~~~~~~~~~~~~~

/get message from pi
void get_message(int n){
~~~~~~~~
  }else if((cmd[0] >= 48) && (cmd[0] < 79)) //0x30~0x4F return message state 
  {
  	message_state = cmd[0];
  }
~~~~~~~~
}


~~~~~~~~~~~~~~

//send message to pi
void send_message(){
  //when get cmd switch
  switch (message_state) {
~~~~~~~~
   //analog read
   case 0x31: //water temp upper bit
   Wire.write(r_wtmp >> 8);
   break;
   case 0x32: //water temp low bit
   Wire.write(r_wtmp & 0xFF);
   break;
   case 0x33: //oil temp upper bit
   Wire.write(r_otmp >> 8 );
   break;
   case 0x34: //oil temp low bit
   Wire.write(r_otmp & 0xFF);
   break;
   case 0x35: //oil press upper bit
   Wire.write(r_opls >> 8);
   break;
   case 0x36: //oil press low bit
   Wire.write(r_opls & 0xFF);
   break;
   case 0x37: //battery level upper bit
   Wire.write(r_b_lv >> 8);
   break;
   case 0x38: //battely level low bit
   Wire.write(r_b_lv & 0xFF);
   break;
 
~~~~~~~~
 }
}

~~~~~~~~~~~~~~

void check_input()
{
  switch (read_counter){
    case 0:
    r_wtmp=analogRead(WTMP_IN);
    read_counter++;
    break;

    case 1:
    r_otmp=analogRead(OTMP_IN);
    read_counter++;
    break;
 
    case 2:
    r_opls=analogRead(OPLS_IN);
    read_counter++;
    break;
 
    case 3:
    r_b_lv=analogRead(B_LV_IN);
    read_counter++;
    break;
 
    case 4:
    read_counter=0;
    break;
 
  }

}

~~~~~~~~~~~~~~

//main loop
void loop()
{
~~~~~~~~
  switch(ino_state)
  {
~~~~~~~~
    case 0x01: //arduino normal state
      if( (acc==0) && (!slp_interbal_flg) )
      {
        ino_state++; //pi shutdown state
      }
      //check sleep interbal
      else if(slp_interbal_flg)
      {
        if(counter_switch)
        {
          if(millis() > onslp_max_time)
          {
            slp_interbal_flg = false;
          }
        }
        else
        {
          if( (millis() < onslp_past_time) && (millis() > onslp_max_time) )
          {
            slp_interbal_flg = false;
          }
        }
      }else
      {
        check_input();
      }
      break;
~~~~~~~~
}


python side of raspberry pi

arduino_meter.py


import math
~~~~~~~~~~~~~~

#thermistor config
THERM_B=4181
THERM_R1=3.00
THERM_R0=2.3
THERM_T0=298.15

~~~~~~~~~~~~~~

#get thermistor
def get_therm(tmp):
    if ( tmp <= 0) | ( tmp > 1023):
        TMP = 1
    else:
       TMP = tmp
    temp = 0
    rr1 = THERM_R1 * TMP / (1024.0 - TMP)
    t = 1 / ( math.log( rr1/THERM_R0 ) / THERM_B  +  1/THERM_T0 )
    temp = (t - 273.5)
    return int(temp)

#get oil_press
def get_oil_press(tmp):
    vol = (5000/1023)*tmp
    press = (vol-600)/40
    return press

~~~~~~~~~~~~~~
#get car data
def get_analog_level(addr,u_data,l_data):
    TRY1 = I2C_TRY
    TRY2 = I2C_TRY
    analog_leve=0
    while TRY1:
        try:
            reading = int(bus.read_byte_data(addr,u_data))
            analog_level = reading << 8
        except IOError as e:
            print "get car data IO error"
            TRY1-=1
        except :
            print "get car date Unexcepted error"
            raise
        else:
            break

    if not TRY1:
        raise

    while TRY2:
        try:
            reading = int(bus.read_byte_data(addr,l_data))
            analog_level = analog_level | reading
            return analog_level
        except IOError as e:
            print "get car data IO error"
            TRY2-=1
        except :
            print "get car date Unexcepted error"
            raise
        else:
            break

    if not TRY2:
        raise
~~~~~~~~~~~~~~

#write data
def write_data():
    m_data = {"wtmp":"" , "otmp":"" ,"opls": ""}
    m_data["wtmp"]=get_therm(w_temp)
    m_data["otmp"]=get_therm(o_temp)
    m_data["opls"]=get_oil_press(o_press)
    with open('meter_data.json','w') as f:
        json.dump(m_data, f, sort_keys=True, indent=4)

~~~~~~~~~~~~~~

    #main loop
    while True:
        check_state(SLAVE_ADDRESS)
        w_temp = get_analog_level(SLAVE_ADDRESS,0x31,0x32)
        o_temp = get_analog_level(SLAVE_ADDRESS,0x33,0x34)
        o_press = get_analog_level(SLAVE_ADDRESS,0x35,0x36)
        b_level = get_analog_level(SLAVE_ADDRESS,0x38,0x38)
        write_data()
        time.sleep(0.1)

~~~~~~~~~~~~~~

Simple connection diagram

The sensor uses the PK series made by Auto Gauge on the market for both temperature and oil pressure. It doesn't matter what the manufacturer is if you take the data, but since there is data from the previous work, I use it as it is. 回路説明図.png

Recommended Posts

Create a car meter with raspberry pi
Using a webcam with Raspberry Pi
Make a wash-drying timer with a Raspberry Pi
Operate an oscilloscope with a Raspberry Pi
GPGPU with Raspberry Pi
DigitalSignage with Raspberry Pi
Create a visitor notification system using Raspberry Pi
Create a socket with an Ethernet interface (eth0, eth1) (Linux, C, Raspberry Pi)
Mutter plants with Raspberry Pi
Create a color sensor using a Raspberry Pi and a camera
Using Akizuki Denshi's 4WD car FT-MC-004 with Raspberry Pi
Create a heatmap with pyqtgraph
I tried to create a button for Slack with Raspberry Pi + Tact Switch
Create a directory with python
A memorandum when making a surveillance camera with Raspberry Pi
Create an LCD (16x2) game with Raspberry Pi and Python
Create a partition and then install the Raspberry Pi OS
I made a resource monitor for Raspberry Pi with a spreadsheet
getrpimodel: Recognize Raspberry Pi model (A, B, B +, B2, B3, etc) with python
I made a surveillance camera with my first Raspberry PI.
Creating a temperature / humidity monitor with Raspberry Pi (pigpio version)
[Raspberry Pi] Stepping motor control with Raspberry Pi
Use vl53l0x with Raspberry Pi (python)
Servo motor control with Raspberry Pi
Serial communication with Raspberry Pi + PySerial
Create a virtual environment with Python!
OS setup with Raspberry Pi Imager
Try L Chika with raspberry pi
Try moving 3 servos with Raspberry Pi
Create a poisson stepper with numpy.random
Create a file uploader with Django
Control the motor with a motor driver using python on Raspberry Pi 3!
Let's make a cycle computer with Raspberry Pi Zero (W, WH)
I made a web server with Raspberry Pi to watch anime
Make a Kanji display compass with Raspberry Pi and Sense Hat
[Note] Using 16x2-digit character LCD (1602A) from Python with Raspberry Pi
Measure SIM signal strength with Raspberry Pi
Create a Python function decorator with Class
Pet monitoring with Rekognition and Raspberry pi
Build a blockchain with Python ① Create a class
[Raspberry Pi] Add a thermometer and a hygrometer
Create a dummy image with Python + PIL.
Hello World with Raspberry Pi + Minecraft Pi Edition
[Python] Create a virtual environment with Anaconda
Let's create a free group with Python
Create a GUI app with Python's Tkinter
Get BITCOIN LTP information with Raspberry PI
Try fishing for smelt with Raspberry Pi
Create a large text file with shellscript
Improved motion sensor made with Raspberry Pi
Create a VM with a YAML file (KVM)
Try Object detection with Raspberry Pi 4 + Coral
Power SG-90 servo motor with raspberry pi
Create a word frequency counter with Python 3.4
Working with sensors on Mathematica on Raspberry Pi
Create a Connecting Nearest Neighbor with NetworkX
Infer Custom Vision model with Raspberry Pi
Create a web service with Docker + Flask
Create a devilish picture with Blender scripts
Create a matrix with PythonGUI (text box)
Inkbird IBS-TH1 value logged with Raspberry Pi