Thread Tools
This thread is privately moderated by grmis, who may elect to delete unwanted replies.
Jan 09, 2014, 08:24 AM
Registered User
grmis's Avatar
Thread OP
Mini-HowTo

5$ magnetic RPM meter for FrSky telemetry


Since I have some trouble to set up the governor mode of my YEP-40A ESC... I thought that it would be nice to build a cheap & simple RPM (headspeed)-meter for my HK450 heli, using the FrSky telemetry [D4R-II receiver & FLD-02 display, but without the FrSky sensor hub]. This has probably be done by someone else before (?), but let me detail how it works anyway.

A tiny neodymium magnet is glued into a hole drilled in the auto-rotation gear. The passing of the magnet is probed by a Hall effect sensor [ref: A3144, 10 for less than 3$ on ebay].

The output of the the Hall sensor is connected to a digital input D3 of an Arduino Pro mini controller [5v/16MHz version, less than 4$ oneBay] (+ pull up resistor). The Arduino detects a pulse each time the magnet comes in front of the sensor (through an ISR interrupt). It measures the time elapsed between consecutive pulses, and therefore can compute the RPM. NB: At 3000rpm there are "only" 50 pulses per second, and the Arduino has plenty of time to do other things if needed.

The result is sent by the Arduino to the FrSky receiver via a serial line (digital pin D2 & "SoftSerial" library).

Some remarks about the hardware:
- Putting the magnet on the autorotation gear seems better than on then main gear, because then one can see the RPM even when the motor is not running (useful for bench tests, or during real "autos").
- Because the magnet (diameter 2mm, height 2mm, N35 grade) is so light, I think that it is not necessary to put two of them on opposite sides to achieve some balance. On the other hand, the gear should be reasonably straight because the sensor has to be fixed (CA glued in my case) very close (at ~ 2mm) to the gear.
- The Arduino is powered by 5v taken from the receiver (mine is working in PPM mode, so th GND and 5v pins of CH2 are not used).

Notes about the Arduino sketch:
- I used some parts of the openxvario code.
- The RPM is sent twice: once as the FrSky "count per second" variable (hence the displayed rpm is multiple of 60), and also as temperature "TEMP2", so that one can see it on the FLD-02 main screen (together with battery voltage). The later is also more precise because it can be any integer, not necessarily multiple of 60.

Possible improvements:
- Modify the code to display also the min and max RPM values measured in the last 20s or so (to see afterwards how it has changed during a pitch pump for instance).
- Automatically stop the timer when the headspeed is below, say, 1500rpm. So one would get the real flight time.
- Monitor the ESC temperature with an external temp. sensor.

Please post some message here if you have some suggestions or questions (or just to say if you found this useful !)

Code:
// GRMIS on RCGROUPS
// The FrSky part of the code was taken from that of the "openxvario" code.
//
// Arduino Pro Mini connected (pin D3) to Hall effect sensor
// Arduino pin D2 connected to 'RX' line of FrSky D4R-2 receiver
// through digital Pin (use SoftSerial with inversion)

#include <SoftwareSerial.h> // To communicate with the FrSky RX
#include <Time.h> 

int rpm; 
volatile long int last; // keyword "Volatile" means that this variable may be changed by a routine called by some interrupt.
volatile long int period;

#define PIN_HallSensor 3
#define PIN_SerialTX 2       // the pin to transmit the serial data to the frsky telemetry enabled receiver
#define PIN_Led 13

// Software Serial is used including the Inverted Signal option ( the "true" in the line below )
// The corresponding pin has to be connected to the 'rx' pin of the receiver
SoftwareSerial mySerial(0, PIN_SerialTX,true);

#define FRSKY_USERDATA_TEMP1        0x02
#define FRSKY_USERDATA_RPM          0x03
#define FRSKY_USERDATA_TEMP2        0x05

#define FRSKY_USERDATA_GPS_HM       0x17
#define FRSKY_USERDATA_GPS_SEC      0x18

unsigned long lastMillisFrame1,lastMillisFrame2,lastMillisFrame3,startMillis;

//_______________________________________________
void setup() {
  rpm=0;   
  pinMode(PIN_HallSensor, INPUT); 
   attachInterrupt(1, Count, FALLING);// Interrupt n1 corresponds to Digital Pin #3

  // set the data rate for the SoftwareSerial port
  // this is the speed of the UART of the FrSky  receiver
  mySerial.begin(9600);
}
//_______________________________________________
void Count() { // Routine called (interrupt n1) each time pin #3 goes from 1 to 0. 
  long int now=micros();
  period=now-last;
  last=now;
}
void loop() {
  
  // Frame to send every 300ms
  if( (lastMillisFrame1 + 300) <=millis()) {
      long int now=micros();
    if (now-last<period) {
      rpm=60000000/period;  
    } else {
        rpm=60000000/(now-last);
    }
    SendRPM();
  lastMillisFrame1=millis();
   
  // Frame to send every 1s
  if( (lastMillisFrame2 + 1000) <=millis()) { 
    SendSec();
    lastMillisFrame2=millis();

    // Frame to send every 10s
    if( (lastMillisFrame3 + 10000) <=millis()) {
      SendHourMinutes();    
      lastMillisFrame3=millis();
    }
  }}
}
//_______________________________________________

void SendValue(uint8_t ID, uint16_t Value) {
  uint8_t tmp1 = Value & 0x00ff;
  uint8_t tmp2 = (Value & 0xff00)>>8;
  mySerial.write(0x5E);
  mySerial.write(ID);
  if(tmp1 == 0x5E) {
    mySerial.write(0x5D);
    mySerial.write(0x3E);
  }
  else if(tmp1 == 0x5D) {
    mySerial.write(0x5D);
    mySerial.write(0x3D);
  }
  else {
    mySerial.write(tmp1);
  }
  if(tmp2 == 0x5E) {
    mySerial.write(0x5D);
    mySerial.write(0x3E);
  }
  else if(tmp2 == 0x5D) {
    mySerial.write(0x5D);
    mySerial.write(0x3D);
  }
  else {
    mySerial.write(tmp2);
  }
  mySerial.write(0x5E);
}
//_______________________________________________

void SendRPM() {
  SendValue(FRSKY_USERDATA_RPM, rpm/60);
  SendValue(FRSKY_USERDATA_TEMP2,rpm);
}

void SendSec() {
  SendValue(FRSKY_USERDATA_GPS_SEC, second());
}
void SendHourMinutes() {
  const uint16_t hm=  ( ( minute()& 0x00ff)<<8 )+ (hour() & 0x00ff);
  SendValue(FRSKY_USERDATA_GPS_HM,hm);
}
Last edited by grmis; Jan 12, 2014 at 03:04 PM. Reason: typos...
Sign up now
to remove ads between posts
Jan 11, 2014, 08:17 AM
Registered User
sirzeppu's Avatar
This is cool. Thanks!
Jan 30, 2014, 11:39 PM
efx
efx
Rookie in training, heads up
efx's Avatar
Nice...how are you getting 6 channels from that receiver? Someone mentioned it before but I forgot and I like the smaller size.
Jan 31, 2014, 03:37 AM
Registered User
grmis's Avatar
Thread OP
Quote:
Originally Posted by efx View Post
Nice...how are you getting 6 channels from that receiver? Someone mentioned it before but I forgot and I like the smaller size.
If you short the signal pins of Ch 3 and Ch4, the D4R-II goes into the "PPM sum" (or "Combined PPM"/"CPPM") mode, which means that the data for 8 channels are sent through the Ch1 pin. As for Ch2, it outputs the RSSI in PWM form. For more details you may have a look at the manual on the FrSky site.
Jan 31, 2014, 03:55 AM
efx
efx
Rookie in training, heads up
efx's Avatar
Great, thanks.

Quote:
Originally Posted by grmis View Post
If you short the signal pins of Ch 3 and Ch4, the D4R-II goes into the "PPM sum" (or "Combined PPM"/"CPPM") mode, which means that the data for 8 channels are sent through the Ch1 pin. As for Ch2, it outputs the RSSI in PWM form. For more details you may have a look at the manual on the FrSky site.
Jan 20, 2016, 05:19 PM
Done Posting, Gone Flying
JNJO's Avatar
I replaced the Hall-sensor with a photosensitive diode.
Instant RPM telemetry from my glow-engines.
Thanks for sharing this, you saved me a lot of headache on getting the telemetry part to work.
Jan 21, 2016, 03:58 AM
Registered User
grmis's Avatar
Thread OP
Quote:
Originally Posted by JNJO View Post
I replaced the Hall-sensor with a photosensitive diode.
Instant RPM telemetry from my glow-engines.
Thanks for sharing this, you saved me a lot of headache on getting the telemetry part to work.
Hi. Thanks for your message !
Is the diode working with visible light or infrared ? Maybe you could post a picture ?
Jan 21, 2016, 04:45 AM
Done Posting, Gone Flying
JNJO's Avatar
It's an IR-diode. I'm using a https://www.elfa.se/en/ir-photodiode...229/p/17510007 , but anyone should do the job.
A 330 ohm resistor and a 10k pot in series to the anode to regulate sensitivity.

I'll do some live tests to verify accuracy, then I'll post a schematic.
Jan 21, 2016, 05:01 AM
Done Posting, Gone Flying
JNJO's Avatar
Your code should also be plug-and-play for the EagleTree brushless RPM-sensor. I have one and will test that.
and it looks like the Orange BL-sensor might work too.

I'll also order this the next time to test as optical sensor.
Turnigy TGY-CPD02 Optical RPM Sensor
EDIT: Does not work with grmis solution or OpenXSensor.
It outputs unknown data, not pulses.
The pulses coming from the sensor itself are about 2.5V, and not high enough to trigger the interrupt.


On the to-do list is to see if I can use pawelsky's FrSky S-Port telemetry library to use S-Port recievers.
EDIT: What looks like a ready solution to S.Port (and old hub) is already done, of course.
https://openxsensor.github.io/
Last edited by JNJO; Feb 19, 2016 at 06:15 AM.
Jan 27, 2016, 04:56 PM
Done Posting, Gone Flying
JNJO's Avatar
The EagleTree brushless RPM-sensor worked just fine, but it has a design flaw:
The red wire is GND and the black wire is 5V.
White is signal and goes to Promini pin D4.

For the optical part, I ended up using a photo transistor instead. Much easier to get readings from.
The one I used is this: https://www.elfa.se/en/ir-phototrans...p3c/p/17522735

This will only work well in daylight, but that's all I'm interested in.

I suggest using a 10-20 kOhm potentiometer to determine a good resistor value.

The signal line will go high when the phototransistor is blocked from light.
Schematic below:
Jan 28, 2016, 01:30 AM
Registered User
grmis's Avatar
Thread OP
Great !
Apr 21, 2016, 11:36 AM
Registered User
Quote:
Originally Posted by JNJO View Post
I'll also order this the next time to test as optical sensor.
Turnigy TGY-CPD02 Optical RPM Sensor
EDIT: Does not work with grmis solution or OpenXSensor.
It outputs unknown data, not pulses.
The pulses coming from the sensor itself are about 2.5V, and not high enough to trigger the interrupt.


On the to-do list is to see if I can use pawelsky's FrSky S-Port telemetry library to use S-Port recievers.
EDIT: What looks like a ready solution to S.Port (and old hub) is already done, of course.
https://openxsensor.github.io/
JNJO: Can you elaborate on your experience with the Turing Optical RPM sensors?

Is the Turnigy TGY-CPD02 Optical RPM Sensor taking the signal from the optical sensor and converting it? Is there some kind of circuit inside the box?

Had you looked at the APD01 version of that sensor?
Turnigy TGY-APD01 Optical RPM Sensor

I'm curious if there is a way to use these as they are 50% off right now in the USA East warehouse and look good, but I'm unsure about the signal output or if it can be easily modified...
Apr 21, 2016, 02:48 PM
Done Posting, Gone Flying
JNJO's Avatar
Yep,
The CPD02 sensor has a chip in it that converts the pulses from the sensor head.
Presumably to something the Turnigy recievers can read and use.
There's not a whole lot of documentation on the Turnigy system to be had, unfortunately, so I gave up on that.

I tried these two also:
https://www.hobbyking.com/hobbyking/s...c_Sensors.html
and
https://www.hobbyking.com/hobbyking/s...ith_cable.html
Both worked well on the bench. I haven't had the chance to test them in the air yet.

The APD02 is a magnetic sensor. I would guess it uses a hall-effect sensor and converts the pulses in the same way as the CPD02.

grmis design in post #1 would be a better choice if a magnetic sensor is what you need.

Happy Tinkering,
Apr 22, 2016, 01:38 PM
Registered User
Quote:
Originally Posted by JNJO View Post
Yep,
The CPD02 sensor has a chip in it that converts the pulses from the sensor head.
Presumably to something the Turnigy recievers can read and use.
There's not a whole lot of documentation on the Turnigy system to be had, unfortunately, so I gave up on that.

I tried these two also:
https://www.hobbyking.com/hobbyking/s...c_Sensors.html
and
https://www.hobbyking.com/hobbyking/s...ith_cable.html
Both worked well on the bench. I haven't had the chance to test them in the air yet.

The APD02 is a magnetic sensor. I would guess it uses a hall-effect sensor and converts the pulses in the same way as the CPD02.

grmis design in post #1 would be a better choice if a magnetic sensor is what you need.

Happy Tinkering,
Oops, I didn't realize the APD01 was magnetic. I'm actually planning to put an Optical (IR) sensor into my project RC vehicle. I have an oscilliscope so I may just order one and see what the signal is. If it's not an easy digital signal I may just cut the cables and run it straight into an arduino or something...

I'll update you guys with what I figure out
Oct 07, 2018, 11:42 AM
RC pilot by soul
Hello guys,

has anyone done just the RPM part? id like to adopt it to my S.port code.


Quick Reply
Message:
Thread Tools