Driving analogue temperature gauge and tacho from 90's Suzuki using iPDM56

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:

  1. 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)

  1. 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);
	}
}


Sorry but I am not a bike person and what you are showing does not indicate anything to me. Start with an annotated schematic and links to the meter sources that give technical information.

Cheers!
Assuming a Honda Civic from a similar vintage works the same way (it's also 3 wire), the tacho should probably be driven with a square wave.
I found this lovely writeup: EG Civic Tachometer Repair - Honda-Tech - Honda Forum Discussion

Here is the drawing: