@Yveaux I did some extensive testing on the FC1816 module and I thought I might drop my experience:
http://electronics.stackexchange.com/questions/226031/pinout-of-microwave-motion-sensor-fc1816
In the end I used an 150ohm Series resistor + ~100µF cap behind this to power the FC1816. This eliminated much of the leftover noise. If this is not enough I presented a way to lower the module amplification. In the end I deactivated the biss-trigger output alltogether and grabbed the raw signal. Doing some manual processing:
- take 100 reads
- get the stddev (statistics library)
- high stddev = high fluctuation in values = movement
Take a look at my current working copy of my code for the FC1816:
Some notes:
I power the VCC of the FC1816 from some arduino pins. Thus I can deactivate the microwave sensor at will. This is still not recommended. If you visit the previous link you can see that the BISS has some kind of "warmup"-Period.
I use 3,3Volt to power the NRF24, the arduino and the FC1816 and suffered no strange consequences so far.
Get get some insight about the link quality of the NRF24 I made the function RF24_getObserverTX() accessible from user-space:
MySensors\drivers\RF24\RF24.cpp
uint8_t RF24_getObserveTX(void)
{
return RF24_readByteRegister(OBSERVE_TX);
}
MySensors\drivers\RF24\RF24.h
uint8_t RF24_getObserveTX(void);
The Idea behind the OBSERVE_TX register is that the lower byte presents the number of retrys the NRF24 used in the last send.
The upper 4 bits present the number of total failed packets. I suggest using (0x0F & RF24_getObserveTX()) to get a usable number 0-15 presenting the retry-count. Anything > 0 suggests a packetloss on your link. 15 most likely will mean you ran into an complete fail as the max number of retrys was exhausted.
This number might be capped by
// ARD, auto retry count
#define RF24_ARC 15
from the RF24.h driver-file.
TO not run into compiling errors you might need:
http://arduiniana.org/libraries/streaming/
https://github.com/RobTillaart/Arduino/tree/master/libraries/Statistic
MicrowaveRadarSensor.ino
#include <Streaming.h>
#include "Statistic.h"
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*******************************
*
* REVISION HISTORY
* Version 1.0 - Henrik EKblad
*
* DESCRIPTION
* Example sketch showing how to measue light level using a LM393 photo-resistor
* http://www.mysensors.org/build/light
*/
#define MY_NODE_ID 10
#define MY_BAUD_RATE 57600
// Enable debug prints to serial monitor
//#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69
#include <SPI.h>
#include <MySensors.h>
#define LIGHT_SENSOR_ANALOG_PIN A3
#define MICRO_SENSOR_ANALOG_PIN A1
unsigned long SLEEP_TIME = 1000; // Sleep time between reads (in milliseconds)
#define CHILD_ID_LIGHT 0
#define CHILD_ID_MICRO 0
#define TRIPPED_THRESHOLD 50
MyMessage msg_light(CHILD_ID_LIGHT, V_LIGHT_LEVEL); // 23
MyMessage msg_micro(CHILD_ID_MICRO, V_TRIPPED); // 16
MyMessage msg_micro_debug(0,V_VAR1); // 24
MyMessage msg_obstx_debug(0,V_VAR2); // 25
void before()
{
// LightSensor
pinMode(A3,INPUT_PULLUP);
pinMode(A2,OUTPUT);
digitalWrite(A2,LOW);
// Microwave
pinMode(5,OUTPUT); // VCC BISS0001
digitalWrite(5,HIGH);
pinMode(6,OUTPUT); // Enabled
digitalWrite(6,LOW); // Enable
pinMode(7,OUTPUT); // GND
digitalWrite(7,LOW);
pinMode(8,OUTPUT); // VCC Radar
digitalWrite(8,HIGH);
pinMode(A1,INPUT); // PIR 2nd Amplification Stage
// Other
}
void setup()
{
}
void presentation() {
// Send the sketch version information to the gateway and Controller
sendSketchInfo("Microwave+Light", "1.0");
// Register all sensors to gateway (they will be created as child devices)
// https://www.mysensors.org/download/serial_api_20#sensor-type
present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
present(CHILD_ID_MICRO, S_MOTION);
//present(0, S_ARDUINO_NODE);
}
void loop()
{
// Report VCC
static long vcc = readVcc();
static int vccpercent = map(vcc,1800,3280,0,100);
sendBatteryLevel(max(min(vccpercent,100),0),false);
Serial << "| vcc: ";
p(F("%4d"),vcc);
Serial << " ";
// Required for ack
//wait(100);
// Report LightLevel
analogRead(LIGHT_SENSOR_ANALOG_PIN);
int lightLevel_raw = analogRead(LIGHT_SENSOR_ANALOG_PIN);
int lightLevel = (1023-lightLevel_raw)/10.23; // as of 1023 !!
Serial << "| light_raw: ";
p(F("%4d"),lightLevel_raw);
Serial << " ";
Serial << "| light: ";
p(F("%3d"),lightLevel);
Serial << " ";
send(msg_light.set(lightLevel),false);
// Report WirelessLink Information
Serial << "| observe_tx: ";
uint8_t obstx = RF24_getObserveTX();
p(F("%X"),obstx);
Serial << " ";
send(msg_obstx_debug.set(0x0F&obstx),false);
// Report Microwave
Statistic mw_s;
mw_s.clear();
delay(90);
analogRead(MICRO_SENSOR_ANALOG_PIN);
delay(10);
for(int i = 0; i < 1000; i++)
{
mw_s.add(analogRead(MICRO_SENSOR_ANALOG_PIN));
delay(1);
}
Serial << "| mw_raw: ";
int stddev = mw_s.pop_stdev();
p(F("%4d"),stddev);
Serial << " ";
Serial << "| mw_min: ";
int minimum = mw_s.minimum();
p(F("%4d"),minimum);
Serial << " ";
Serial << "| mw_max: ";
int maximum = mw_s.maximum();
p(F("%4d"),maximum);
Serial << " ";
Serial << "| mw: " << (stddev > TRIPPED_THRESHOLD ? "1" : "0") << " ";
send(msg_micro_debug.set(stddev),false);
while(!send(msg_micro.set(stddev > TRIPPED_THRESHOLD ? "1" : "0"),true))
{
wait(10);
}
if(isTransportOK())
wait(100);
else
wait(1000);
Serial << endl;
//mysleep(500);
}
// https://forum.mysensors.org/topic/3463/m_ack_variable-or-m_set_variable/2
void receive(const MyMessage &message) {
if (message.isAck()) {
Serial.print("| GW ack");
}
}
Helper.ino
long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high<<8) | low;
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
//result *= 1.0637;
return result; // Vcc in millivolts
}
#include <stdarg.h>
void p(const __FlashStringHelper *fmt, ... ){
char buf[128]; // resulting string limited to 128 chars
va_list args;
va_start (args, fmt);
#ifdef __AVR__
vsnprintf_P(buf, sizeof(buf), (const char *)fmt, args); // progmem for AVR
#else
vsnprintf(buf, sizeof(buf), (const char *)fmt, args); // for the rest of the world
#endif
va_end(args);
Serial.print(buf);
}
void mysleep(int SLEEP_TIME)
{
if(isTransportOK()){
Serial << "| wait ";
wait(25);
Serial << "| zZz > ";
sleep(SLEEP_TIME);
Serial << "| < zZz " << endl;
}
else {
wait(1000);
}
}