Wednesday, June 19, 2024

nodemcu12-f esp8266 flow sensor result ISR not in IRAM!

if we use esp8266 and have error ISR not in IRAm when we use interrupt

then we must code like this :

int sensorPin = 2;
volatile long pulse = 0;

// Declare the increase function prototype

void IRAM_ATTR increase() { // use this IRAM_ATTR
  pulse++;
}

void setup() {
  pinMode(sensorPin, INPUT_PULLUP);
  Serial.begin(115200);
  attachInterrupt(digitalPinToInterrupt(sensorPin), increase, FALLING);
}

void loop() {
  Serial.println(pulse);
  delay(500);
}



Thursday, May 5, 2022

arduino lightning thunder emi filter - low frequency filter

 Emi from thunder/ lightning generate low frequency that can make electromagnet interference (EMI) effect in long cable

so we should shield the input output arduino from low frequency emi 

this how i do that



Friday, August 23, 2019

BLYNK NODEMCU ULTRASONIC JSN-SR04T WATER LEVEL

nodemcu waterproof ultrasonic jsn-sr04t for water level using blynk

//****Virtual Pin Assignments****

// V0 - Blynk Version - labeled value
// V1 - ESP Version    - labeled value
// V2 - Millis Uptime  - labeled value
// V3 - Wifi RSSI        - labeled value
// V4 - Volume            - labeled value
// V8 - Terminal          - terminal
// V9 - Percent            - level V widget -- value 1 -10
//V10 - Numeric Widget - Level Alert
//V11 - Button Widget to cancel alert or turn alert (on or off) --button
//V12 - Distance - height from sensor to water level  -- labeled value

//#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#include <ESP8266mDNS.h>  // For OTA w/ ESP8266
#include <WiFiUdp.h>  // For OTA
#include <ArduinoOTA.h>  // For OTA

char auth[] = "yourAuthCode";

char ssid[] = "changeto your ssid";
char pass[] = "yourpassword";

BlynkTimer timer;

WidgetTerminal terminal(V8);

#define echoPin 14// Echo Pin
#define trigPin 12  // Trigger Pin

#define filterSamples   3              // filterSamples should  be an odd number, no smaller than 3

int maximumRange = 450;
int minimumRange = 20;
int alertLevelCounter = 0; //Counter starts at zero
int volume;
int volume1; // for smoothing algorithum
int percent;
int percent1; // for smoothing algorithum
int levelAlert;
int wateralert = 0;
int sensSmoothArray1 [filterSamples];   // array for holding raw sensor values for sensor1 
int smoothDistance;                     // variables for sensor1 data

double alertInMin = 0.5;                //Alert time following alert water level being reached (0.5 = 30secs)

const int alertDuration = 2;            //Alert sent every 2 minutes

const int waterTankDia = 80;           //Water Tank Diameter (cm)
const int waterTankHt = 100;            //ie. Sensor Height (cm)

long jarak,jarak1;
long duration, distance, distance1;     // Duration used to calculate distance


BLYNK_CONNECTED() { // runs once at device startup, once connected to server.
  Blynk.syncVirtual(V10);
  Blynk.syncVirtual(V11);
}
void MeasureCm() {
 //  The following trigPin/echoPin cycle is used to determine the
 // distance of the nearest object by bouncing soundwaves off of it. 
 digitalWrite(trigPin, LOW); 
 delayMicroseconds(2); 

 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10); 
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 //Calculate the distance (in cm) based on the speed of sound.
 distance = duration/58.2;
 if(distance >= 20 ){
 volume = ((waterTankHt*(PI*(sq(waterTankDia/2))))-(distance*(PI*(sq(waterTankDia/2)))))/1000;
 //percent = ((float)volume/9000)*100;
  //jarak = 1-(distance/100);
  //volume = ((0.4 * 0.4 * (1-(distance/100))) *(22/7))*1000;
  percent = (100 - distance);
  //percent = 100 - (distance/3);
   } 
 else{
     if(distance < 20 ){
       volume = 450;
       percent = 100;
     }
 }

  Blynk.virtualWrite(V9, percent); // virtual pin
  Blynk.virtualWrite(V12, distance); // virtual pin
  Blynk.virtualWrite(V4, volume); // virtual pin

void UpTime() {
  Blynk.virtualWrite(2, (millis() / 1000));
  Blynk.virtualWrite(3, WiFi.RSSI());
  //terminal.println(levelAlert);
}


BLYNK_WRITE(V10) {
  levelAlert = param.asInt();
  terminal.print("Water Level Alert: ");
  terminal.println(levelAlert);
  terminal.println();
  terminal.flush();
   
BLYNK_WRITE(V11) { 

  int alertOff = param.asInt();

  if(alertOff == 0) {
resetWaterLevelAlert();
wateralert = 1;
terminal.print("Level Alert is OFF");
terminal.println();
terminal.flush();
  }
  else {
resetWaterLevelAlert();
wateralert = 0;
terminal.print("Level Alert is ON");
terminal.println();
terminal.flush();
  }

}


void checkWaterLevel() {
  
  if(volume1 < levelAlert && wateralert == 0){
 alertLevelCounter += 1;
  }

  if(alertLevelCounter > alertInMin * 60 && wateralert == 0){
Blynk.notify("Water Tank Level Alert"); // send push notification to blynk app
wateralert = 1;
resetWaterLevelAlert();
  }
}

void resetWaterLevelAlert() {
  alertLevelCounter = 0;
  wateralert = 0;
}


void MeasureCmForSmoothing() {
  /* The following trigPin/echoPin cycle is used to determine the
 distance of the nearest object by bouncing soundwaves off of it. */ 

 digitalWrite(trigPin, LOW); 
 delayMicroseconds(2); 

 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10); 
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);

 //Calculate the distance (in cm) based on the speed of sound.
 distance1 = duration/58.2; //for smoothing algorithim

 smoothDistance = digitalSmooth(distance1, sensSmoothArray1);

 {
 if(distance1 >= 20 ) {
   volume1 = ((waterTankHt*(PI*(sq(waterTankDia/2))))-(smoothDistance*(PI*(sq(waterTankDia/2)))))/1000;
   //volume1 = ((((0.4 * 0.4) * (1-(smoothDistance/100))) *(22/7))*1000);
  percent1 = (100 - smoothDistance);

   terminal.print("Uptime (secs): ");
   terminal.println((millis() / 1000));
   terminal.print("Distance: ");
   terminal.println(distance1);
   terminal.print("Smoothed Distance: ");
   terminal.println(smoothDistance);
   terminal.println();
      terminal.print("percent1: ");
   terminal.println(percent1);
   terminal.flush();
   //terminal.print("Percent: ");
   // terminal.println(percent1);
 } 
   else{
    if(distance1 < 20 ){
      volume1 = 450;
      percent1 = 100;
    }
   }  
 }

void UploadMeasureCmForSmoothing() {
Blynk.virtualWrite(V12, smoothDistance); // virtual pin
Blynk.virtualWrite(V4, volume1); // virtual pin
Blynk.virtualWrite(V9, percent1); // virtual pin
  
terminal.print("Uploaded Volume: ");
terminal.println(volume1);
terminal.print("Uploaded Smoothed Distance: ");
terminal.println(smoothDistance);
terminal.println();

terminal.flush();

}

  

void setup() {
 Serial.begin(115200);
 Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 8080);

 ArduinoOTA.setHostname("Water_Tank");  // For OTA - Use your own device identifying name
 ArduinoOTA.begin();  // For OTA

 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);

 terminal.clear();
  timer.setTimeout(100, [](){
 timer.setInterval(5000L, UpTime);
 });

 timer.setTimeout(400, [](){
 timer.setInterval(300000L, UploadMeasureCmForSmoothing);  //get a measurement straight up if the device was reset for some reason
 });

 timer.setTimeout(600, [](){
 timer.setTimer(1000L, MeasureCm, 1);
 });
  
 timer.setTimeout(500, [](){
 timer.setInterval(1000L, checkWaterLevel);
 });

 timer.setTimeout(700, [](){
 timer.setInterval(15000L, MeasureCmForSmoothing);
 });

}
void loop() {
  Blynk.run(); // Initiates Blynk
  ArduinoOTA.handle();  // For OTA
  timer.run(); // Initiates SimpleTimer
}

int digitalSmooth(int rawIn, int *sensSmoothArray){     // "int *sensSmoothArray" passes an array to the function - the asterisk indicates the array name is a pointer
int j, k, temp, top, bottom;
long total;
static int i;
// static int raw[filterSamples];
static int sorted[filterSamples];
boolean done;

i = (i + 1) % filterSamples;    // increment counter and roll over if necc. -  % (modulo operator) rolls over variable
sensSmoothArray[i] = rawIn;                 // input new data into the oldest slot

// Serial.print("raw = ");

 for (j=0; j<filterSamples; j++){     // transfer data array into anther array for sorting and averaging
     sorted[j] = sensSmoothArray[j];
 }

   done = 0;                // flag to know when we're done sorting              
 while(done != 1){        // simple swap sort, sorts numbers from lowest to highest
      done = 1;
        for(j = 0; j < (filterSamples - 1); j++){
           if(sorted[j] > sorted[j + 1]){     // numbers are out of order - swap
             temp = sorted[j + 1];
             sorted [j+1] =  sorted[j] ;
             sorted [j] = temp;
             done = 0;
           }
        }
  }

/*
  for (j = 0; j < (filterSamples); j++){    // print the array to debug
Serial.print(sorted[j]); 
Serial.print("   "); 
  }
  Serial.println();
*/
   // throw out top and bottom 15% of samples - limit to throw out at least one from top and bottom
   //  bottom = max(((filterSamples * 15)  / 100), 1); 
   //  top = min((((filterSamples * 85) / 100) + 1  ), (filterSamples - 1));   // the + 1 is to make up for asymmetry caused by integer rounding
   bottom = max(((filterSamples * 20)  / 100), 1); 
   top = min((((filterSamples * 80) / 100) + 1  ), (filterSamples - 1));   // the + 1 is to make up for asymmetry caused by integer rounding
   k = 0;
   total = 0;
  for( j = bottom; j< top; j++){
 total += sorted[j];  // total remaining indices
 k++; 
 //Serial.print(sorted[j]); 
 //Serial.print("   "); 
 //terminal.print(sorted[j]); 
 //terminal.println("   ");
  
  }
   //terminal.print("average: ");
   //terminal.println(total/k);
   //terminal.flush();
   //Serial.println();
   //Serial.print("average = ");
   //Serial.println(total/k);
  return total / k;    // divide by number of samples
}

Wednesday, February 13, 2019

arduino 4 channel relay jd-vcc

for my own documentation .
this picture was taken from outseal.com

no need ground from arduino,
this relay is LOW ACTIVE


Arduino HC12 with DFplayer

i want to make bell using HC-12 long range 433mhz with dfplayer


here is the code

////////////////////////////////////////////////////////////////////////////////////////////////////////////
///// RECEIVER //////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// HC-12 TRANSCEIVER
// RECEIVER (RX) part

#include <SoftwareSerial.h> // import the necessary library
#include <DFPlayer_Mini_Mp3.h>
SoftwareSerial hc12(10, 9); // TX - RX-- HC-12
SoftwareSerial myMP3(12, 11); // bener 12/11

char incomingByte;
String readBuffer = "";
const int led     = 5;
const int setPin = 7; // pin used to set up the HC-12 wireless module


void setup() {
  pinMode(setPin, OUTPUT); //  setPin on hc12
  digitalWrite(led, LOW);

  Serial.begin(9600);
  hc12.begin(9600); // Start the software serial port
  Serial.println("start");

  digitalWrite(setPin, LOW);
  //hc12.print("AT+DEFAULT");
  hc12.print("AT+B19200");
  hc12.print("AT+C001");
  digitalWrite(setPin, HIGH);


  myMP3.begin(9600);
  mp3_set_serial (myMP3);
  delay(400);
  mp3_reset();
  delay(400);
  mp3_set_volume(15);
  delay(1000);
}

void loop() {
  hc12.listen();
  while (hc12.available()) {
    Serial.println("GET data");
    incomingByte = hc12.read();
    readBuffer += char(incomingByte);
    Serial.println(readBuffer);
    if (readBuffer == "bel") {
      hc12.print("bel1");
      //Serial.println("GET DATA 2");
      mp3_play (1); //PLAY SONG 0001.mp3
      delay(14000L);
      readBuffer = "";
    } // bel

    // PLAYING ANOTHER SOUND
    if (readBuffer == "ob" ) {
      hc12.print("ob1");
      mp3_play (2);
      delay(14000L);
      readBuffer = "";
    } //calling my office boy
  }

}



/////////////////////////////////////////////////////////////////////////////////
//TRANSMITTER
//////////////////////////////////////////////////////////////////////////////
// HC-12 TRANSCEIVER
// TRANSMITTER (TX) part


#include <SoftwareSerial.h>
SoftwareSerial hc12(11, 9); //  TX-RX pins on Arduino

const int pcnPin = 3; // pin connected to the output of the client alarm system
const int setPin = 7; // pin used to set up the HC-12 wireless module
const int led     = 5; //confirmation led blink
int var = 0;
int flag = 0;
unsigned long start, skrg;
unsigned long interval = 1000UL * 60 * 0.5;
char incomingByte;
String readBuffer = "";
void setup() {
  pinMode(setPin, OUTPUT);
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
  pinMode(pcnPin, INPUT_PULLUP); // my alarm system will ground the dry contact upon alarm

  hc12.begin(9600); // start the software serial port
  Serial.begin(9600);

  digitalWrite(setPin, LOW);
  //hc12.print("AT+DEFAULT");
  hc12.print("AT+B19200");
  hc12.print("AT+C001");
  digitalWrite(setPin, HIGH);

}
void loop() {

  if (digitalRead(pcnPin) == LOW && flag == 0) {
    start = millis();
    digitalWrite(led, HIGH);
    delay(200);
    digitalWrite(led, LOW);
    delay(200);
    flag = 1;
  }
  skrg = millis();
  if ( skrg - start > interval ) {
    flag = 0;
    //Serial.println("reset push");
  }
  if (digitalRead(pcnPin) == LOW && flag == 1) {
    hc12.print("bel");
    digitalWrite(led, HIGH);
    delay(200);
    digitalWrite(led, LOW);
    delay(200);
    digitalWrite(led, HIGH);
    delay(200);
    digitalWrite(led, LOW);
    delay(200);

    while (hc12.available()) {
      incomingByte = hc12.read();
      readBuffer += char(incomingByte);
    }
  }
  if (readBuffer == "") {
    flag = 1;
    hc12.print("bel");
  }
  if (readBuffer == "bel1") {
    flag = 0;
  }

  delay(100);

}