How to read an analog frequency?

I was hoping you folks might have some idea how to code something I’m working on with the photon. I’m thinking of using a photoresistor to read the status of the (aftermarket) Bluetooth module in my truck to lock the doors if motion is sensed and its not connected to my phone, also to unlock the doors if motion is sensed and my phone is connected. I will install a motion sensor that pulls a digital pin low with motion.
Part one:
If the led is flashing then write Bluetooth status is low (disconnected) , if the led is solid then write Bluetooth status high (connected).
Part two:
If Bluetooth value is low (phone not connected) and a digital input goes low (motion detected), trigger D7 high (lock doors).

And

If Bluetooth value is high (phone connected) and digital input goes low (motion detected), trigger D7 low (unlock doors).

The connection status is a blue led that blinks when searching and solid when paired. I have installed a photoresistor into the unit and it reads 400bits when off and 3500bits when on. it flashes about 2 times a second when pairing but goes right to solid when turned on and the phone is in range.

So how do i use an analog frequency reading to trigger an if statement?

The led flashes around 2hz, I have tried to average the readings so if its blinking the average is lower but it seems to get into some type of phase problem where it reads a bunch of high numbers then a bunch of low numbers. It really needs to be an instantaneous thing such as: if theres motion, turn on the bluetooth, read for 2 seconds and if there are any low readings lock the doors. If there are only high readings, unlock the doors.

below is my current code, its a bit messy as i keep trying new things. Any help is appreciated!!

//#pragma SPARK_NO_PREPROCESSOR
#include "blynk/blynk.h"
#include "blynk/BlynkSimpleParticle.h"
#include "SparkCorePolledTimer/SparkCorePolledTimer.h"
#include "spark-dallas-temperature/spark-dallas-temperature.h"
#include "OneWire/OneWire.h"
#include "MCP23008-I2C/MCP23008-I2C.h"  //I2C STUFF
#define ONE_WIRE_BUS D6                 // Data wire is plugged into pin D5 on the particle
#define TEMPERATURE_PRECISION 12        // DS18B20 Thermometer Stuff
//#define lock BLYNK_WRITE(7)             // lock doors
//#define unlock BLYNK_WRITE(6)           // unlock doors

//char auth[] = "84c4567bbd7a41f28a132ee281f3d156";  //BLYNK CE4
//char auth[] = "a0eb3774535f476a92aa19a0b906f991";  //BLYNK CE3
char auth[] = "7e4f909b23e94418b41507e855fc3d62";  //BLYNK CE2

OneWire oneWire(ONE_WIRE_BUS);          // DS18B20 Thermometer Stuff
DallasTemperature sensors(&oneWire);    // DS18B20 Thermometer Stuff
Adafruit_MCP23008 mcp;                  // I2C STUFF
SparkCorePolledTimer updateTimer(5000); //Create a timer object and set it's timeout in milliseconds
void OnTimer(void);                     //Prototype for timer callback method

float main, mainRaw, aux, auxRaw, acc, accRaw, light, lightRaw;
float bt, btRaw;


//averaging stuff
//const int aIn = A4;
//int positive;
//unsigned long period;
//unsigned long mark;
//end averaging stuff


//int lock(String command);
//int unlock(String command);


//defince temp address
DeviceAddress Thermometer1 = { 0x28, 0xFF, 0x44, 0x50, 0x16, 0x15, 0x3, 0xC };
DeviceAddress Thermometer2 = { 0x28, 0xFF, 0xD5, 0x4D, 0x16, 0x15, 0x3, 0xD3 };
DeviceAddress Thermometer3 = { 0x28, 0xFF, 0x2D, 0x37, 0x16, 0x15, 0x3, 0xF8 };
DeviceAddress Thermometer4 = { 0x28, 0xFF, 0x6A, 0x24, 0x16, 0x15, 0x3, 0xF0 };
//DeviceAddress Thermometer5 = { 0x28, 0xFF, 0xF5, 0x4F, 0x16, 0x15, 0x3, 0x2C };
// define temp bit resolution ie: int, float, double
double InTempC = -1;
double Temp1 = -1;
double Temp2 = -1; 
double Temp3 = -1;
double Temp4 = -1;
//double Temp5 = -1;
void update18B20Temp(DeviceAddress deviceAddress, double &tempC);
//end temp stuff

 //setupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetupsetup 
void setup(){
Serial.begin(9600);
Blynk.begin(auth);      // BLYNK initialization
updateTimer.SetCallback(OnTimer);
//Particle.function("lock", lock);
//Particle.function("unlock", unlock);

//averging
// while(analogRead(aIn)>512);//wait for positive half period to expire
//  while(analogRead(aIn)<512);//wait for negative half period to expire
//  mark = micros();//zero crossing from negative to positive found
//  while(analogRead(aIn)>512);//wait for positive half period to expire
//  while(analogRead(aIn)<512);//wait for negative half period to expire
//  period = micros()-mark;
//averaging


    sensors.begin();    // DS18B20 initialization
    sensors.setResolution(Thermometer1, TEMPERATURE_PRECISION);
    sensors.setResolution(Thermometer2, TEMPERATURE_PRECISION); 
    sensors.setResolution(Thermometer3, TEMPERATURE_PRECISION);
    sensors.setResolution(Thermometer4, TEMPERATURE_PRECISION);
//    sensors.setResolution(Thermometer5, TEMPERATURE_PRECISION);
pinMode(A0, INPUT); //
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A4, INPUT); //BLUETOOTH PHOTORESISTOR
pinMode(A5, INPUT);

//pinmode(lock, OUTPUT);
//pinmode(unlock, OUTPUT);



// I2C STUFF
mcp.begin();      // use default address 0
  mcp.pinMode(0, OUTPUT); 
  mcp.pinMode(1, OUTPUT);
  mcp.pinMode(2, OUTPUT);
  mcp.pinMode(3, OUTPUT);
  mcp.pinMode(4, OUTPUT);
  mcp.pinMode(5, OUTPUT);
  mcp.pinMode(6, OUTPUT);
  mcp.pinMode(7, OUTPUT);
// END I2C STUFF
}// END VOID SETUP BUT WHAT ABOUT I2C CODE BELOW BEFORE LOOP

// BLYNY WRITE NEEDS TO BE ABOVE LOOP BUT NOT IN SETUP LIKE THIS
// I2C STUFF
BLYNK_WRITE(0) {
    if (param.asInt()) {
        mcp.digitalWrite(0, HIGH);
        delay(3000);        
    } else {
       mcp.digitalWrite(0, LOW);}}
       
BLYNK_WRITE(1) {
    if (param.asInt()) {
        mcp.digitalWrite(1, HIGH);
    } else {
       mcp.digitalWrite(1, LOW);}}
       
BLYNK_WRITE(2) {
    if (param.asInt()) {
        mcp.digitalWrite(2, HIGH);
    } else {
       mcp.digitalWrite(2, LOW);}}
       
BLYNK_WRITE(3) {
    if (param.asInt()) {
        mcp.digitalWrite(3, HIGH);
    } else {
       mcp.digitalWrite(3, LOW);}}
       
BLYNK_WRITE(4) {
    if (param.asInt()) {
        mcp.digitalWrite(4, HIGH);
    } else {
       mcp.digitalWrite(4, LOW);}}
       
BLYNK_WRITE(5) {
    if (param.asInt()) {
        mcp.digitalWrite(5, HIGH);
    } else {
       mcp.digitalWrite(5, LOW);}}
       
BLYNK_WRITE(6) {
    if (param.asInt()) {
        mcp.digitalWrite(6, HIGH);
        delay(500);   
        mcp.digitalWrite(6, LOW);
        delay(500);  
        mcp.digitalWrite(6, HIGH);
        delay(500); 
    } else {
       mcp.digitalWrite(6, LOW);}}
        
BLYNK_WRITE(7) {
    if (param.asInt()) {
        mcp.digitalWrite(7, HIGH);
        delay(500);   
        mcp.digitalWrite(7, LOW);
        delay(500);  
        mcp.digitalWrite(7, HIGH);
        delay(500); 
    } else {
       mcp.digitalWrite(7, LOW);}}
//I2C STUFF


//looplooplooplooplooplooplooplooplooplooplooplooplooplooplooplooplooplooplooplooplooplooplooploop//looplooplooplooplooplooploopl
void loop()
{
Blynk.run();
updateTimer.Update();

}

void OnTimer(void) { //Handler for the timer, will be called automatically
        // DS18B20
        sensors.requestTemperatures();
        update18B20Temp(Thermometer1, InTempC);
        Temp1 = (InTempC * 9)/5 + 32;
        update18B20Temp(Thermometer2, InTempC);  
        Temp2 = (InTempC * 9)/5 + 31.33;  
        update18B20Temp(Thermometer3, InTempC);  
        Temp3 = (InTempC * 9)/5 + 31.67;  
        update18B20Temp(Thermometer4, InTempC);  
        Temp4 = (InTempC * 9)/5 + 32; 
//        update18B20Temp(Thermometer5, InTempC);
//        Temp5 = (InTempC * 9)/5 + 32.12;
//delay(5000); // READ DELAY - TOOK THIS OUT AND IT GOT JUMPY WITH -127'S C AND 196'S F        
updateTimer.Update();    // new stuff
}

void update18B20Temp(DeviceAddress deviceAddress, double &tempC)
{
  tempC = sensors.getTempC(deviceAddress);

// read temperature and discard reading between 150 and -30
if ( Temp1 < 150 && Temp1 > -30) {
    Blynk.virtualWrite(21, Temp1); 
}
if ( Temp2 < 150 && Temp2 > -30) {
    Blynk.virtualWrite(22, Temp2); 
}
if ( Temp3 < 150 && Temp3 > -30) {
    Blynk.virtualWrite(23, Temp3);
}
if ( Temp4 < 150 && Temp4 > -30) {
    Blynk.virtualWrite(24, Temp4);
}
//if ( Temp5 < 150 && Temp5 > -30) {
//    Blynk.virtualWrite(25, Temp5);
//}

// read analog ports
mainRaw = analogRead(A0);
auxRaw = analogRead(A1);
accRaw = analogRead(A2);
lightRaw = analogRead(A5);
btRaw = analogRead(A4);

// map analog input scale output
main = map(mainRaw, 0, 4096, 0, 1865);
aux = map(auxRaw, 0, 4096, 0, 1865);
acc = map(accRaw, 0, 4096, 0, 1865);
light = map(lightRaw, 0, 4050, 1100, 1500);
bt = map(btRaw, 300, 3500, 0, 100);
// correct display decimal place
main = (main / 100);
aux = (aux / 100);
acc = (acc / 100);
light = (light / 100);

Blynk.virtualWrite(10, main);
Blynk.virtualWrite(11, aux);
Blynk.virtualWrite(12, acc);
Blynk.virtualWrite(15, light);

Blynk.virtualWrite(14, bt);


}

This guy wrote some stuff: http://jeelabs.org/2012/03/18/detecting-a-blinking-led/

I think you need to make sure you have the correct resistance from what I can tell to separate the values from each others, e.g. go from low to high.

I think you need to measure how it takes to go from dark to light and if that exceeds a certain time, than do your lock/unlock routing

if(timeBetweenBlinks > 2000) { openDoors() } else { lockDoors }

Something like that in pseudo-code.

Would this be easier with a digital signal? I can use an optoisolator/coupler, I’m not making any progress with the analog signal trigger.

Maybe it would because you probably only have to deal with HIGH and LOW values and count them and the time in between. I try to use digital information when I only need 1 or 0 or something similar. I try to preserve the analog inputs for sensory data. To me that makes sense (but then again, I’m a bit weird, lol)

I have installed an a/d converter and now I have a digital hi/low when blinking and a high when steady. What’s the most efficient way to read the difference? A Boolean true false would be great. Would pulses over time require another library for frequency sampling?

What I do with my light sensors is indeed an average over a certain period of time. I use an array to do that.

Something along the lines of:

  // Number of readings you want to take
  const byte readings = 9;
  
  // Start up arrays for taking measurements
  int valueRed[readings];
  int valueGreen[readings];
  int valueBlue[readings];

  // Read analog ports
  for(int i=0;i<readings;i++)
  {
    valueRed[i]   = analogRead(A0);
    valueGreen[i] = analogRead(A1);
    valueBlue[i]  = analogRead(A2);
    delay(10);
  }

After that you can read out the array(s) and do your things with it. This one takes about 1 second I think (9x 10ms), but you can adjust that to your needs of course :slight_smile: