I'm stuck with adding EV gauges to my motorbike conversion and can't even figure out the hardware.
Background on the project is at ES: Suzuki RF400E, now with Enertrac MHM602 | Endless Sphere DIY EV Forum
The "Arduino" I'm using is Celeron55's iPDM56, basically an Uno clone with 2x CAN bus, robust power supply, automotive inputs and outputs. It should be very capable for this use case as we have both low and high ("12V") digital and analogue outputs. More details: GitHub - celeron55/ipdm56
Current test setup:
The two clocks from the connector side:
- The temperature gauge
Measurements [Ohms]:
Br | B/Y - 220
W/Y | B/Y - 117
W/Y | Br - 117
Frankly, the third connector confounds me.
I have played with high side PWM on this one as it's resistive between Temp + and Temp - on the connector. Above 35/255 the needle starts moving up but never stops, so it doesn't "hold", so I moved on.
Posting here made me realize that I haven't mapped the connections from gauge to connector, here they are:
W/Y is B/G Temp +
B/Y is B/Br Temp - & B/W Illumi/Tacho - (bridged)
Br is O Tacho, Temp + (i.e. shared between both)
- The tacho
From what I've read this is likely an air core gauge which normally requires a special driver. I'm getting lost at Air core gauge - Wikipedia. I could live with <20 steps if the fomula is a bit much.
Measurements [Ohms]:
B | B/W - 200K
B/W | O - 180
B | O - 199K
Mappings:
O is O Tacho, Temp + (i.e. shared between both)
B/W is B/Br Temp - & B/W Illumi/Tacho - (bridged)
B is Tacho Signal +
/*
ipdmsw - iPDM56 firmware template
Copyright (c) 2023 Perttu "celeron55" Ahola
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "src/ipdm_library.h"
#include "src/ipdm_util.h"
#include "src/ipdm_can.h"
#include "src/params.h"
// Matrix inputs/outputs
constexpr int UNUSED_M1 = A0; // A0 = M1
constexpr int UNUSED_M2 = A1; // A1 = M2
constexpr int UNUSED_M3 = A2; // A2 = M3
constexpr int UNUSED_M4 = A3; // A3 = M4
constexpr int UNUSED_M5 = A6; // A6 = M5
constexpr int UNUSED_M6 = 2; // D2 = M6
constexpr int UNUSED_M7 = 3; // D3 = M7
constexpr int UNUSED_M8 = ipdm::ED4; // ED4 = M8
constexpr int UNUSED_M9 = ipdm::ED5; // ED5 = M9
constexpr int UNUSED_M10 = ipdm::ED6; // ED6 = M10
// Digital outputs
constexpr int LOUT1 = ipdm::LOUT1;
constexpr int LOUT2 = ipdm::LOUT2;
constexpr int UNUSED_LOUT3 = ipdm::LOUT3;
constexpr int UNUSED_LOUT4 = ipdm::LOUT4;
constexpr int UNUSED_LOUT5 = ipdm::LOUT5;
constexpr int UNUSED_LOUT6 = ipdm::LOUT6;
constexpr int UNUSED_HOUT1 = ipdm::HOUT1;
constexpr int UNUSED_HOUT2 = ipdm::HOUT2;
constexpr int UNUSED_HOUT3 = ipdm::HOUT3;
constexpr int UNUSED_HOUT4 = ipdm::HOUT4;
constexpr int UNUSED_HOUT5 = ipdm::HOUT5;
constexpr int UNUSED_HOUT6 = ipdm::HOUT6;
// PWM outputs
constexpr int UNUSED_LPWM1 = ipdm::LPWM1;
constexpr int LPWM2 = ipdm::LPWM2;
constexpr int AOUT1 = ipdm::AOUT1;
constexpr int UNUSED_AOUT2 = ipdm::AOUT2;
constexpr int LPWM3 = ipdm::LPWM3;
constexpr int LPWM4 = ipdm::LPWM4;
// Variables
int32_t pwm_dec = 1;
void setup()
{
Serial.begin(115200);
ipdm::setup();
// The MCP2515 CAN controllers will be initialized with these speeds and
// filters when the 5Vsw rail is powered up using ipdm::enable_switched_5v()
ipdm::can1_params.speed = CAN_500KBPS;
ipdm::can2_params.speed = CAN_500KBPS;
// You can set the CAN filters like this. By default all messages pass.
/*ipdm::can1_params.filter1_mask = 0xfff;
ipdm::can1_params.filter1_ids[0] = 0x123;
ipdm::can1_params.filter1_ids[1] = 0x456;
ipdm::can1_params.filter2_mask = 0xff0;
ipdm::can1_params.filter2_ids[0] = 0x120;
ipdm::can1_params.filter2_ids[1] = 0x340;
ipdm::can1_params.filter2_ids[2] = 0x560;
ipdm::can1_params.filter2_ids[3] = 0x780;*/
}
void loop()
{
ipdm::loop();
EVERY_N_MILLISECONDS(30000){
ipdm::util_print_timestamp(Serial);
Serial.println("-!- iPDM56 running");
REPORT_UINT16_HYS(analogRead_mV_factor16(ipdm::VBAT_PIN, ipdm::ADC_FACTOR16_VBAT), 100);
}
// Always enable switched 5V
if(true){
ipdm::enable_switched_5v();
} else {
ipdm::disable_switched_5v();
}
// PWMs
EVERY_N_MILLISECONDS(1000){
if (pwm_dec > 10000) {
pwm_dec = 100;}
else {
pwm_dec = pwm_dec + 200 ;}
Serial.print("pwm_dec: ");
Serial.println(pwm_dec);
}
tone(AOUT1, pwm_dec, 100);
}
// -------------------------------- Functions ------------------------------------------
static void print_frame(const CAN_FRAME &frame)
{
Serial.print("id=0x");
Serial.print(frame.id, HEX);
for(uint8_t i=0; i<8; i++){
Serial.print(" 0x");
Serial.print(frame.data.bytes[i], HEX);
}
}


