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);

}



Friday, May 25, 2018

ARDUINO - DFPLAYER WITH DS3231

#include <SPI.h>                   
#include <Wire.h>
#include <DS3231.h>
#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
#include <Button.h>
DS3231  rtc(SDA, SCL);
Time  t;
uint8_t hh = 0, mm = 0, ss = 0;
SoftwareSerial mySerial(11, 10); // Declare pin RX & TX

#define BUTTON8 8 // tombol ON
#define PULLUP true
#define INVERT true
#define DEBOUNCE_MS 20
Button btn1(BUTTON8, PULLUP, INVERT, DEBOUNCE_MS);

int b1 = 3; //tombol on/off
const int busyPin = 5; //Dfplayer -busypin will be HIGH if mp3 stop play
int busyStatus =0;
int led = 13;
void setup() {
  Serial.begin(57600);
  pinMode (busyPin, INPUT);
  pinMode(b1, INPUT_PULLUP);
  rtc.begin();
  mySerial.begin (9600);
  mp3_set_serial (mySerial); //set softwareSerial for DFPlayer
  delay(10);
  mp3_reset();
  delay(10);   //wait 1ms for respon command
  mp3_set_volume (30); //Set volume value. From 0 to 30
  delay(500);
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
  //rtc.setTime(8, 38, 0);     // Set the time to 12:00:00 (24hr format)
  //rtc.setDate(25, 5, 2018);   // Set the date to January 1st, 2014
}


void loop() {

  t = rtc.getTime();  // gate all data time & date from RTC
  hh = t.hour, DEC; //pengambilan data jam
  mm = t.min, DEC; //pengambilan data menit
  ss = t.sec, DEC; //pengambilan data detik
 
    Serial.print(hh);
    Serial.print(":");
    Serial.print(mm);
    Serial.print(":");
    Serial.println(ss);
    delay(1000);
  Serial.println(digitalRead(busyPin));

  if (btn1.read() == 1 ) { // nyalain mp3
    digitalWrite(led, HIGH);
    mp3_play(1);
    delay(1000);
    digitalWrite(led, LOW);
    //delay(56000);
 }



  if (hh >= 6 && hh <= 22 ) {
    busyStatus = digitalRead(busyPin);
    if ( busyStatus == HIGH ) {
      mp3_play(1);
      digitalWrite(led, HIGH);
    }
  }
 
  else {
    mp3_stop();
    digitalWrite(led, LOW);
  }
 

}

Wednesday, April 5, 2017

READING AC 220 V arduino ZMPT101B

https://github.com/openenergymonitor/EmonLib

// EmonLibrary examples openenergymonitor.org, Licence GNU GPL V3

#include "EmonLib.h"             // Include Emon Library
EnergyMonitor emon1;             // Create an instance

int i = 0;
float tenvals = 0.0;
float minval = 1000;
float maxval = 0.0;

void setup()
{
  Serial.begin(115200);
 
  emon1.voltage(2, 109, 1.7);  // Voltage: input pin, calibration, phase_shift
//  emon1.current(1, 111.1);       // Current: input pin, calibration.
}

void loop()
{
  emon1.calcVI(20,2000);         // Calculate all. No.of half wavelengths (crossings), time-out
//  emon1.serialprint();           // Print out all variables (realpower, apparent power, Vrms, Irms, power factor)
 
//  float realPower       = emon1.realPower;        //extract Real Power into variable
//  float apparentPower   = emon1.apparentPower;    //extract Apparent Power into variable
//  float powerFActor     = emon1.powerFactor;      //extract Power Factor into Variable
//  float supplyVoltage   = emon1.Vrms;             //extract Vrms into Variable
//  float Irms            = emon1.Irms;             //extract Irms into Variable

 float Vrms = (emon1.Vrms - 3);
 if (Vrms < 0) { Vrms = 0.0; }

 tenvals += Vrms;
 if (minval > Vrms) { minval = Vrms; }
 if (maxval < Vrms) { maxval = Vrms; }

 i++;

 if (i == 10)
 {
  Serial.print("Avg: ");
  Serial.print(tenvals/10);
  Serial.print(" (");
  Serial.print(Vrms);
  Serial.print(") Min: ");
  Serial.print(minval);
  Serial.print(" Max: ");
  Serial.println(maxval);

  i = 0;
  tenvals = 0.0;
  minval = 1000.0;
  maxval = 0.0;
 }
  delay(100);
}


Friday, March 17, 2017

ARDUINO COUNTER USING IR SENSOR FC-51

arduino counter using IR sensor FC-51 is for use at bathroom or toilet
for counting people in and out, if the counter is zero, then it will turn off the light



#define in 5
#define out 7
#define relay 2
#define power 9
int pinIn;
int pinOut;
int statusIn= 0;
int statusOut;
int count=0;
void IN()
{
    count++;
    //Serial.println(count);
    delay(1000);
}
void OUT()
{
  count--;
  //Serial.println(count);
  delay(1000);
}
void setup()
{
  Serial.begin(9600);
  delay(2000);
  pinMode(in, INPUT);
  pinMode(out, INPUT);
  pinMode(relay, OUTPUT);
  pinMode(power, OUTPUT);
  digitalWrite(power, HIGH);
}
void loop()
{
    Serial.println(count);
    //ada halangan 0
    pinIn = digitalRead(in);
    if(statusIn == 0 && pinIn == 0 && pinOut == 0){
      IN();
      statusIn = 1;
    }
    if(statusIn == 1 && pinIn == 1){
      statusIn =0;
    }

    pinOut = digitalRead(out);
    if(statusOut == 0 && pinOut == 0 && pinIn == 0){
      OUT();
      statusOut = 1;
    }
    if(statusOut == 1 && pinOut == 1){
      statusOut =0;
    }
}




================================
arduino bathroom ligh saving
arduino on off bathroom light
arduino automatic switch off bathroom if no people inside
lampu toilet otomatis
contact : veluska@gmail.com (at indonesia-jakarta)

arduino genset detect volt





Thursday, January 26, 2017

ARDUINO LOAD CELL 50 KG


First, you must using 4 load cell 50 kg for balance
please watch this tutorial


first do the calibration
=================================================================
#include "HX711.h"  //You must have this library in your arduino library folder ,search in github

#define DOUT  3
#define CLK  2

HX711 scale(DOUT, CLK);

//Change this calibration factor as per your load cell once it is found you many need to vary it in thousands
//float calibration_factor = -96650; //-106600 worked for my 40Kg max scale setup 
 float calibration_factor = 190; 
//=============================================================================================
//                         SETUP
//=============================================================================================
void setup() {
  Serial.begin(9600);
  Serial.println("HX711 Calibration");
  Serial.println("Remove all weight from scale");
  Serial.println("After readings begin, place known weight on scale");
  Serial.println("Press a,s,d,f to increase calibration factor by 10,100,1000,10000 respectively");
  Serial.println("Press z,x,c,v to decrease calibration factor by 10,100,1000,10000 respectively");
  Serial.println("Press t for tare");
  scale.set_scale();
  scale.tare(); //Reset the scale to 0

  long zero_factor = scale.read_average(); //Get a baseline reading
  Serial.print("Zero factor: "); //This can be used to remove the need to tare the scale. Useful in permanent scale projects.
  Serial.println(zero_factor);
}

//=============================================================================================
//                         LOOP
//=============================================================================================
void loop() {

  scale.set_scale(calibration_factor); //Adjust to this calibration factor

  Serial.print("Reading: ");
  Serial.print(0.453592 * scale.get_units(), 3);
  Serial.print(" kg"); //Change this to kg and re-adjust the calibration factor if you follow SI units like a sane person
  Serial.print(" calibration_factor: ");
  Serial.print(calibration_factor);
  Serial.println();

  if(Serial.available())
  {
    char temp = Serial.read();
    if(temp == '+' || temp == 'a')
      calibration_factor += 10;
    else if(temp == '-' || temp == 'z')
      calibration_factor -= 10;
    else if(temp == 's')
      calibration_factor += 100;  
    else if(temp == 'x')
      calibration_factor -= 100;  
    else if(temp == 'd')
      calibration_factor += 1000;  
    else if(temp == 'c')
      calibration_factor -= 1000;
    else if(temp == 'f')
      calibration_factor += 10000;  
    else if(temp == 'v')
      calibration_factor -= 10000;  
    else if(temp == 't')
      scale.tare();  //Reset the scale to zero
  }
}
=============================================================


load cell in action :


#include "HX711.h"  //You must have this library in your arduino library folder

#define DOUT  3
#define CLK  2

HX711 scale(DOUT, CLK);

//Change this calibration factor as per your load cell once it is found you many need to vary it in thousands
float calibration_factor = 230; //-106600 worked for my 40Kg max scale setup 
double a;
//=============================================================================================
//                         SETUP
//=============================================================================================
void setup() {
  Serial.begin(9600);  
  Serial.println("Press T to tare");
  scale.set_scale(calibration_factor);  //Calibration Factor obtained from first sketch
 // scale.tare();             //Reset the scale to 0  
}

//=============================================================================================
//                         LOOP
//=============================================================================================
void loop() {
  Serial.print("Weight: ");
  Serial.print((0.453592 * scale.get_units(3))/10, 1);  //Up to 3 decimal points
  Serial.println(" kg"); //Change this to kg and re-adjust the calibration factor if you follow lbs
  float a = ((0.453592 * scale.get_units(3))/10);
  Serial.println(a,1);
  if(a,1 >= 0.8){
    Serial.println("stop");
  }
  if(Serial.available())
  {
    char temp = Serial.read();
    if(temp == 't' || temp == 'T'){
      scale.tare();  //Reset the scale to zero }
    }
    if(temp == 'a'){
      scale.set_scale(calibration_factor);
      scale.tare();
    }
  }
}

Tuesday, January 17, 2017

arduino TDS meter - cheap tds

just for my documentation
please refer to real web :
https://hackaday.io/project/7008-fly-wars-a-hackers-solution-to-world-hunger/log/24646-three-dollar-ec-ppm-meter-arduino


Parts:

-MCU of your choice with ADC

-DS18B20 waterproof temperature sensor

-500 ohm [or 1kohm resistor]

-Type A Two Prong american plug to Figure 8

-Female Socket for Figure 8 connector

So why are we using a plug:

-Cheap

-Available worldwide

-Standard size [makes calibration easy]

Use the solid prong one like below and not the one with holes:

 Wiring it up:

Note: You want the Solid Prong type plug

Do not Plug the pronged plug into the mains





Operating Principal

PPM is calculated from the EC of a fluid, EC is the inverse of the electrical resistance of the fluid. We are estimating the EC or PPM of a fluid by measuring the resistance between two probes [The plug pins] when the plug is submerged in the liquid of interest.

Ec measurement needs to be done using AC or the liquid of interest is polarised and will give bad readings. This has got to be a great example of asking why instead of just accepting a statement as fact, it turns out we can take a very fast DC reading without suffering polarisation. meaning we can make a really cheap EC sensor.

Want to use it and dont care how it works? Skip to the main EC code and using the wiring diagram it will work.

Temperature Compensation

Temperature has an effect on the conductivity of fluids so it is essential that we compensate for this.

It is common to use a liner approximation for small temperature changes[1] to convert them to their equivelant EC at 25*C:

EC25 = EC /( 1 + a (T - 25) )

EC25- Equivelant EC at 25'C

EC - Measured EC

T- Temperature [Decgrees C] of Measurment

a = 0.019 °C [Commonly used for nutrient solutions]

Deciding on Value of R1

//##################################################################################
//----------- Do not Replace R1 with a resistor lower than 300 ohms ------------
//##################################################################################
We can change the Value of R1 in the voltage divider to change the range of EC we want to measure. Below is the Equivalent Voltage divider circuit.

//************************** Libraries Needed To Compile The Script [See Read me In Download] ***************//
// Both below Library are custom ones [ SEE READ ME In Downloaded Zip If You Dont Know how To install] Use them or add a pull up resistor to the temp probe

#include <OneWire.h>
#include <DallasTemperature.h>

//************************* User Defined Variables ********************************************************//
//##################################################################################
//-----------  Do not Replace R1 with a resistor lower than 300 ohms    ------------
//##################################################################################
int R1= 1000;
int Ra=25; //Resistance of powering Pins
int ECPin= A0;
int ECGround=A1;
int ECPower =A4;


//*********** Converting to ppm [Learn to use EC it is much better**************//
// Hana      [USA]        PPMconverion:  0.5
// Eutech    [EU]          PPMconversion:  0.64
//Tranchen  [Australia]  PPMconversion:  0.7
// Why didnt anyone standardise this?


float PPMconversion=0.5;

//*************Compensating for temperature ************************************//
//The value below will change depending on what chemical solution we are measuring
//0.019 is generaly considered the standard for plant nutrients [google "Temperature compensation EC" for more info
float TemperatureCoef = 0.019; //this changes depending on what chemical we are measuring


//********************** Cell Constant For Ec Measurements *********************//
//Mine was around 2.9 with plugs being a standard size they should all be around the same
//But If you get bad readings you can use the calibration script and fluid to get a better estimate for K
//float K=2.88;
 float K=4.25;

//************ Temp Probe Related *********************************************//
#define ONE_WIRE_BUS 10          // Data wire For Temp Probe is plugged into pin 10 on the Arduino
const int TempProbePossitive =8;  //Temp Probe power connected to pin 9
const int TempProbeNegative=9;    //Temp Probe Negative connected to pin 8

//***************************** END Of Recomended User Inputs *****************************************************************//

OneWire oneWire(ONE_WIRE_BUS);// Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);// Pass our oneWire reference to Dallas Temperature.

float Temperature=10;
float EC=0;
float EC25 =0;
int ppm =0;

float raw= 0;
float Vin= 5;
float Vdrop= 0;
float Rc= 0;
float buffer=0;


//*********************************Setup - runs Once and sets pins etc ******************************************************//
void setup()
{
  Serial.begin(9600);
  pinMode(TempProbeNegative , OUTPUT ); //seting ground pin as output for tmp probe
  digitalWrite(TempProbeNegative , LOW );//Seting it to ground so it can sink current
  pinMode(TempProbePossitive , OUTPUT );//ditto but for positive
  digitalWrite(TempProbePossitive , HIGH );
  pinMode(ECPin,INPUT);
  pinMode(ECPower,OUTPUT);//Setting pin for sourcing current
  pinMode(ECGround,OUTPUT);//setting pin for sinking current
  digitalWrite(ECGround,LOW);//We can leave the ground connected permanantly

  delay(100);// gives sensor time to settle
  sensors.begin();
  delay(100);
  //** Adding Digital Pin Resistance to [25 ohm] to the static Resistor *********//
  // Consule Read-Me for Why, or just accept it as true
  R1=(R1+Ra);// Taking into acount Powering Pin Resitance

  Serial.println("ElCheapo Arduino EC-PPM measurments");
  Serial.println("By: Michael Ratcliffe  Mike@MichaelRatcliffe.com");
  Serial.println("Free software: you can redistribute it and/or modify it under GNU ");
  Serial.println("");
  Serial.println("Make sure Probe and Temp Sensor are in Solution and solution is well mixed");
  Serial.println("");
  Serial.println("Measurments at 5's Second intervals [Dont read Ec morre than once every 5 seconds]:");


};
//******************************************* End of Setup **********************************************************************//




//************************************* Main Loop - Runs Forever ***************************************************************//
//Moved Heavy Work To subroutines so you can call them from main loop without cluttering the main loop
void loop()
{
GetEC();          //Calls Code to Go into GetEC() Loop [Below Main Loop] dont call this more that 1/5 hhz [once every five seconds] or you will polarise the water
PrintReadings();  // Cals Print routine [below main loop]
delay(5000);
}
//************************************** End Of Main Loop **********************************************************************//



//************ This Loop Is called From Main Loop************************//
void GetEC(){

//*********Reading Temperature Of Solution *******************//
sensors.requestTemperatures();// Send the command to get temperatures
Temperature=sensors.getTempCByIndex(0); //Stores Value in Variable



//************Estimates Resistance of Liquid ****************//
digitalWrite(ECPower,HIGH);
raw= analogRead(ECPin);
raw= analogRead(ECPin);// This is not a mistake, First reading will be low beause if charged a capacitor
digitalWrite(ECPower,LOW);


//***************** Converts to EC **************************//
Vdrop= (Vin*raw)/1024.0;
Rc=(Vdrop*R1)/(Vin-Vdrop);
Rc=Rc-Ra; //acounting for Digital Pin Resitance
EC = 1000/(Rc*K);


//*************Compensating For Temperaure********************//
EC25  =  EC/ (1+ TemperatureCoef*(Temperature-25.0));
ppm=(EC25)*(PPMconversion*1000);
;}
//************************** End OF EC Function ***************************//


//***This Loop Is called From Main Loop- Prints to serial usefull info ***//
void PrintReadings(){
Serial.print("Rc: ");
Serial.print(Rc);
Serial.print(" EC: ");
Serial.print(EC25);
Serial.print(" Simens  ");
Serial.print(ppm);
Serial.print(" ppm  ");
Serial.print(Temperature);
Serial.println(" *C ");


/*
//********** Usued for Debugging ************
Serial.print("Vdrop: ");
Serial.println(Vdrop);
Serial.print("Rc: ");
Serial.println(Rc);
Serial.print(EC);
Serial.println("Siemens");
//********** end of Debugging Prints *********
*/
};

Wednesday, January 11, 2017

arduino water flow


Features:
Model: YF-S201
Working Voltage: 5 to 18V DC (min tested working voltage 4.5V)
Max current draw: 15mA @ 5V
Output Type: 5V TTL
Working Flow Rate: 1 to 30 Liters/Minute
Working Temperature range: -25 to +80?
Working Humidity Range: 35%-80% RH
Accuracy: ±10%
Maximum water pressure: 2.0 MPa
Output duty cycle: 50% +-10%
Output rise time: 0.04us
Output fall time: 0.18us
Flow rate pulse characteristics: Frequency (Hz) = 7.5 * Flow rate (L/min)
Pulses per Liter: 450
Durability: minimum 300,000 cycles
Cable length: 15cm
1/2" nominal pipe connections, 0.78" outer diameter, 1/2" of thread
Size: 2.5" x 1.4" x 1.4"



using interupt pin 

const int PinSensorWaterFlowTaman=2;// intr 0 // pin 2 
float flow_countertaman,litertaman,adcph,teg,ph;
const int PinKranTaman =9;//// kran untuk taman 
void setup()
{
 pinMode(PinSensorWaterFlowTaman, INPUT);
        digitalWrite(PinSensorWaterFlowTaman, HIGH); 
        attachInterrupt(0, flowtaman, RISING); // Setup Interrupt 0 pada pin 2
 Serial.begin(9600); 
  pinMode(PinKranTaman,OUTPUT);
        digitalWrite(PinKranTaman,LOW);

}

void loop()
{
 Serial.println(flow_countertaman);
 Serial.println(litertaman);

delay(1000); 
}  

void flowtaman () // Interrupt function taman
    {
      flow_countertaman++;
       litertaman=flow_countertaman/450;
}

Tuesday, January 10, 2017

ACS712 with AC POWER


GREEN = ARDE/GROUND
WHITE = PHASE
BLACK = 0V

copas dari https://www.facebook.com/dani.ardianto.rajacell

//Mengukur arus pada tegangan AC 220V dengan Sensor ACS712
//Analog Output ACS712 pada PIN A0
const int sensorIn = A0;
int mVperAmp = 185;
//Konversi A ke mV
// use 185 for ACS712 5A
// use 100 for ACS712 20A
// use 66 for ACS712 30A
double Voltage = 0;
double VRMS = 0;
double AmpsRMS = 0;
void setup(){
Serial.begin(9600);
}
void loop(){
Voltage = getVPP();
VRMS = (Voltage/2.0) *0.707;
AmpsRMS = (VRMS * 1000)/mVperAmp;
Serial.print(AmpsRMS);
Serial.println(" Amps RMS");
}
float getVPP()
{
float result;
int readValue; //value read from the sensor
int maxValue = 0; // store max value here
int minValue = 1024; // store min value here
uint32_t start_time = millis();
while((millis()-start_time) < 1000) //sample for 1 Sec
{
readValue = analogRead(sensorIn);
// see if you have a new maxValue
if (readValue > maxValue)
{
/*record the maximum sensor value*/
maxValue = readValue;
}
if (readValue < minValue)
{
/*record the maximum sensor value*/
minValue = readValue;
}
}
// Subtract min from max
result = ((maxValue - minValue) * 5.0)/1024.0;
return result;
}

Monday, December 12, 2016

arduino HC-SR04 anti bounching

HC-SR04

unsigned long delay1,delay2;
if (jarak<=30){

if (millis()-delay1>=2000){
digitalWrite(relay,LOW);
}
}
else { delay1=millis();}
if (jaraK>=200){
if (millis()-delay2>=2000){
digitalWrite(relay,HIGH);
}
}
else { delay2=millis();}

Monday, November 28, 2016

NRF24L01 for remote relay

NRF24L01 for remote relay


//receiver

#include <SPI.h>                       // SPI Arayüzünü dahil ettik.
//#include "nRF24L01.h"
#include "RF24.h"                      // RF24 kütüpanelerini dahil ettik.
#include <Wire.h>
#include <DS3231.h>


DS3231  rtc(SDA, SCL);
// Init a Time-data structure
Time  t;
uint32_t targetTime = 0;
uint8_t hh = 0, mm = 0, ss = 0, dd = 0, bb = 0; //variable Unsignet int 0-255
int yy = 0; //variable integer
byte data[1];                          // Göndereceğimiz data değişkenini oluşturduk.
boolean var;                           // Bit şeklinde var değişkeninini oluşturduk.
const uint64_t pipe = 0xF0F0F0F0E1LL;
RF24 radio(9, 10);                     // Modülün CE pinini 9.pin CS pinini de 10.pine bağlayacağımızı belirttik.

int r1 = 0, r2 = 0, r3 = 0;

void setup() {
  Serial.begin(57600);
  pinMode(3, OUTPUT); digitalWrite(3, HIGH);//kolam renang
  pinMode(5, OUTPUT); digitalWrite(5, HIGH);//kolam naga
  pinMode(7, OUTPUT); digitalWrite(7, HIGH); //lampu naga
  radio.begin();                        
  radio.openReadingPipe(1, pipe);      
  radio.startListening();
  rtc.begin();
}

void loop() {

  // NRF remote

  if (radio.available()) {
    bool var = false;
    while (!var) {
      var = radio.read(&data, 1);
    }//while

    if (data[0] == 1 && r1 == 0) {
      digitalWrite(3, LOW);
     // Serial.println("RELAY 3 LOW");
      r1 = 1; data[0] = 0;
    }
    if (data[0] == 1 && r1 == 1 ) {
      digitalWrite(3, HIGH);
      //Serial.println("RELAY 3 HIGH ");
      r1 = 0; data[0] = 0;
    }

    if (data[0] == 2 && r2 == 0) {
      digitalWrite(5, LOW);
      //Serial.println("RELAY 5 LOW");
      r2 = 1; data[0] = 0;
    }
    if (data[0] == 2 && r2 == 1 ) {
      digitalWrite(5, HIGH);
      //Serial.println("RELAY 5 HIGH ");
      r2 = 0; data[0] = 0;
    }

    if (data[0] == 3 && r3 == 0) {
      digitalWrite(7, LOW);
      //Serial.println("RELAY 7 LOW");
      r3 = 1; data[0] = 0;
    }
    if (data[0] == 3 && r3 == 1 ) {
      digitalWrite(7, HIGH);
      //Serial.println("RELAY 7 HIGH ");
      r3 = 0 ; data[0] = 0;
    }
  }//if

  t = rtc.getTime();  // gate all data time & date from RTC
  hh = t.hour, DEC; //pengambilan data jam
  mm = t.min, DEC; //pengambilan data menit
  ss = t.sec, DEC; //pengambilan data detik
  //Serial.print (hh); Serial.print (F(" : "));
  //Serial.print (mm); Serial.print (F(" : "));
  //Serial.println (ss);

  //jam 9 pagi
  if (hh == 10 && mm == 0 && ss == 0) {
    digitalWrite(3, LOW);//kolam renang
    digitalWrite(5, LOW);//kolam naga
    digitalWrite(7, HIGH);//lampu naga //relay 3
  }
  if (hh == 15 &&  mm == 0 && ss == 0) {
    digitalWrite(3, HIGH);//kolam renang
    digitalWrite(5, HIGH);//kolam naga
    digitalWrite(7, HIGH);//lampu naga
  }
delay(1000);
}



// transmitter
#include  <SPI.h>
//#include "nRF24L01.h"
#include  "RF24.h"
#include <PinChangeInterrupt.h>
#include <avr/sleep.h>


volatile byte flag = 0;
void handler() {
    flag = 1;
    //Serial.println("wake up");
    //delay(100);
    detachPinChangeInterrupt(3);
    detachPinChangeInterrupt(5);
    detachPinChangeInterrupt(7);
}

byte data[1];
const uint64_t pipe = 0xF0F0F0F0E1LL;
RF24 radio(9, 10);                    // Modülün CE pinini 9.pin CS pinini de 10.pine bağlayacağımızı belirttik.
unsigned long nowTime;
unsigned long start1;

unsigned long previousMillis = 0;
unsigned long startSleep;

int kirim = 0,btn3,btn5,btn7;
int sleepStatus = 0;             // variable to store a request for sleep
int count = 0;                   // counter
void wakeUpNow()   {}

void setup() {
  Serial.begin(57600);
  pinMode(3, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(7, INPUT_PULLUP);
  pinMode(13, INPUT);
  digitalWrite(13, LOW);
  attachPCINT(digitalPinToPCINT(3), handler, CHANGE);
  attachPCINT(digitalPinToPCINT(5), handler, CHANGE);
  attachPCINT(digitalPinToPCINT(7), handler, CHANGE);
  radio.begin();
  radio.setRetries(15,15);
  radio.openWritingPipe(pipe);
  radio.startListening();
}
void sleepNow(){
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_enable();
      attachPCINT(digitalPinToPCINT(3), handler, CHANGE);
  attachPCINT(digitalPinToPCINT(5), handler, CHANGE);
  attachPCINT(digitalPinToPCINT(7), handler, CHANGE);
    sleep_mode();
    sleep_disable();
    detachPinChangeInterrupt(3);
    detachPinChangeInterrupt(5);
    detachPinChangeInterrupt(7);
}

void loop() {
//Serial.println("bgn");
  btn3 = digitalRead(3);
  btn5 = digitalRead(5);
  btn7 = digitalRead(7);

  if(flag == 1){
      if (btn3==0) {
        data[0] = 1;
        Serial.println("RELAY 3 ");
      }
      else if (btn5==0) {
        data[0] = 2;
        Serial.println("RELAY 5 ");
      }
      else if (btn7==0) {
        data[0] = 3;
        Serial.println("RELAY 7 ");
      }
 
    radio.stopListening();
    radio.write( &data, sizeof(unsigned long) );
    radio.startListening();
    delay(1000);
    data[0]=9;
    flag = 0;
  }//flag
  startSleep = millis();
  if(startSleep - previousMillis >= 3000) {
    previousMillis = startSleep;
    Serial.println("sleep");
    sleepNow();
  }
}//end loop



Monday, November 7, 2016

nodemcu cloudmqtt servo

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Servo.h>
#include<EEPROM.h>

long lastReconnectAttempt = 0;
int servoPin = D4;
bool statusBall;
const char *statusBall2;
bool statusBall3;
int addressEpp = 0;
Servo servo;
const char *statusServo;
const char *ssid =  "ssid";   // cannot be longer than 32 characters!
const char *pass =  "pass";   //

//Prepare Mqtt connection data
const char *MQTTBroker = "cloudmqtt.com";
const char *MQTTuser = "";
const char *MQTTpassword = "";
//const char *Topic = "/kranstatus";
//const char *Topicid = "/kran";
uint16_t port = 12728;


void cekMem(){
    statusBall=EEPROM.read(1);
 // Serial.println(" memory ");
 // Serial.println(statusBall);
  if(statusBall == 1){
    statusBall2 = "on";
    servoOn();
  }
  if(statusBall == 0){
    statusBall2 ="off";
    servoOff();
  }
 // Serial.println("memory part");
   //Serial.println(statusBall2);
}

void servoOn(){
    servo.attach(servoPin);
    servo.write(86);
    delay(800);
    servo.detach();
   // Serial.println("servo on");
    statusBall2 = "on";
    EEPROM.write(1, 1);
}
void servoOff(){
    servo.attach(servoPin);
    servo.write(250);
    delay(800);
    servo.detach();
    //Serial.println("servo off");
    statusBall2 = "off";
    EEPROM.write(1, 0);
}

//PubSubClient mqtt(MQTTBroker,port);
WiFiClient wclient;
PubSubClient client(wclient, MQTTBroker, port);

void callback(const MQTT::Publish& pub){
  //Serial.println(pub.payload_string());
    if(pub.payload_string()=="on" && statusBall2 == "off" ){
    servoOn();
    //Serial.println("call back on");
  }
  if(pub.payload_string()=="off" && statusBall2 == "on"){
    servoOff();
    //Serial.println("call back off");
  }
}
void WIFI_Connect()
{
  WiFi.disconnect(1);
  Serial.println("Booting Sketch...");
  delay(2000);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);
    int Attempt = 0;
    while (WiFi.status() == 6) {
    delay(100);
    Attempt++;
      if (Attempt == 300) {
        ESP.restart();
      }
    }
 
  client.set_callback(callback);  //Set Callback function

  if (client.connect(MQTT::Connect("kran").set_auth(MQTTuser,MQTTpassword))){
    client.publish("kranstatus", statusBall2);  //publish
    client.subscribe("kranstatus");    //subscribe
  }
   // Serial.print("Wifi connect");
    //Serial.println(WiFi.status());
}
void setup()
{
  statusBall=EEPROM.read(1);
  //Serial.print(" memory --");
  //Serial.println(statusBall);
  if(statusBall == 1){
    statusBall2 = "on";
    servoOn();
  }
  if(statusBall == 0){
    statusBall2 ="off";
    servoOff();
  }
  //Serial.print("memory status");
   //Serial.println(statusBall2);
  //Serial.begin(9600);

  WIFI_Connect();
  //client.set_callback(callback);  //Set Callback function

  //if (client.connect(MQTT::Connect("kran").set_auth(MQTTuser,MQTTpassword))){
  //  client.publish("kranstatus", statusBall2);  //publish
  //  client.subscribe("kranstatus");    //subscribe
  //}

}


void loop()
{

      //delay(1000);
      //client.subscribe("kranstatus");
      //client.publish("kranstatus", statusBall2);  //publish
    //Serial.print("status loop ");
    //Serial.println(WiFi.status());
    delay(2000);
    if (WiFi.status() == 6)
    {
      //Serial.println("putus koneksi");
      WIFI_Connect();
    }
    else
    {
      if(!client.subscribe("kranstatus")){
        WIFI_Connect();
      }
      if(!client.publish("kranstatus", statusBall2)){
        WIFI_Connect();
      }

      //delay(1000);
      //client.subscribe("kranstatus");
      //client.publish("kranstatus", statusBall2);  //publish
    }

client.loop();

 
}

Wednesday, October 26, 2016

Nodemcu 12E with servo mg995

#include <ESP8266WiFi.h>
#include <Servo.h>
const char* ssid = "";
const char* password = "";

//int ledPin = 13; // GPIO13
int val = 0;     // variable for reading the pin status
int servoPin = D4;
Servo servo;
int flag = 1;
int tranPin = 14; //Transister base pin

WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  delay(10);
  pinMode(tranPin, OUTPUT);

  Serial.begin(9600);

  servo.attach(servoPin);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.print("Use this URL to connect: ");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");

}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }

  // Read the first line of the request
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();

  // Match the request

  int value = LOW;
  if (request.indexOf("/LED=ON") != -1)  {
    /*
    if(flag ==0){
      digitalWrite(tranPin, HIGH); //turn on servo power
      servo.write(60);
      delay(800);
      digitalWrite(tranPin, LOW); //turn on servo power
      flag = 1;
    }
    */
    servo.attach(servoPin);
    servo.write(60);
    delay(800);
    servo.detach();
    value = HIGH;
  }
  if (request.indexOf("/LED=OFF") != -1)  {
    /*
    if(flag == 1){
      digitalWrite(tranPin, HIGH); //turn on servo power
      servo.write(150);
      delay(800);
      digitalWrite(tranPin, LOW); //turn on servo power
      flag = 0;
    }
    */
    servo.attach(servoPin);
    servo.write(150);
    delay(800);
    servo.detach();
    value = LOW;
  }

// Set ledPin according to the request
//digitalWrite(ledPin, value);

  // Return the response
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println(""); //  do not forget this one
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");

  client.print("Valve is now: ");

  if(value == HIGH) {
    client.print("ON");
  } else {
    client.print("OFF");
  }
  client.println("<br><br>");
  client.println("<a href=\"/LED=ON\"\"><button>Turn On </button></a>");
  client.println("<a href=\"/LED=OFF\"\"><button>Turn Off </button></a><br />");
  client.println("</html>");

  delay(1);
  Serial.println("Client disonnected");
  Serial.println("");

}

Thursday, August 18, 2016

NRF24L01

// http://www.bajdi.com
// Sending a struct with the nRF24L01 module
// Data to be sent is the reading of 2 analog pins
// Data received is the analog reading of 2 pins on the other Arduino 

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

RF24 radio(1,2);  // make sure this corresponds to the pins you are using
const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

const int led = 0;

typedef struct{
  int A;
  int B;
  float C;
  float D;
}
A_t;

typedef struct{
  int W;
  int X;
  float Y;
  float Z;
}
B_t;

A_t duino1;  
B_t duino2; 

void setup()
{
  Serial.begin(57600);
  pinMode(led, OUTPUT);
  radio.begin();
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);
}

void loop(void)
{
  // we need data to sent...
  duino2.W = analogRead(A0);
  duino2.X = analogRead(A1);
  duino2.Y = analogRead(A0)/102.3;
  duino2.Z = analogRead(A1)/102.3;
  // end of analog reading

  // radio stuff
  radio.stopListening();
  bool ok = radio.write( &duino2, sizeof(duino2) );
  radio.startListening();

  unsigned long started_waiting_at = millis();
  bool timeout = false;
  while ( ! radio.available() && ! timeout )
    if (millis() - started_waiting_at > 250 )
      timeout = true;

  if ( timeout )
  {
    Serial.println("Failed, response timed out.");
    digitalWrite(led, HIGH);
  }
  else
  {
    radio.read( &duino1, sizeof(duino1) );
    digitalWrite(led, LOW);
  }
  // end of radio stuff

  // serial print received data
  Serial.print("duino1.A = ");
  Serial.println(duino1.A);
  Serial.print("duino1.B = ");
  Serial.println(duino1.B);
  Serial.print("duino1.C = ");
  Serial.println(duino1.C);
  Serial.print("duino1.D = ");
  Serial.println(duino1.D);
  // end of serial printing
}


============================================================


// http://www.bajdi.com
// Sending a struct with the nRF24L01 module
// Data to be sent is the reading of 2 analog pins
// Data received is the analog reading of 2 pins on the other Arduino 

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

typedef struct{
  int A;
  int B;
  float C;
  float D;
}
A_t;

typedef struct{
  int W;
  int X;
  float Y;
  float Z;
}
B_t;

A_t duino1;  
B_t duino2;

RF24 radio(8,9);   // make sure this corresponds to the pins you are using
const uint64_t pipes[2] = { 
  0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

void setup()
{
  Serial.begin(57600);
  radio.begin();
  radio.openWritingPipe(pipes[1]);
  radio.openReadingPipe(1,pipes[0]);
  radio.startListening();
}

void loop(void)
{ 
  // we need data to sent...
  duino1.A = analogRead(A0);
  duino1.B = analogRead(A1);
  duino1.C = analogRead(A0)/102.3;
  duino1.D = analogRead(A1)/102.3;
  // end of analog reading

  // radio stuff
  if ( radio.available() )
  {
    bool done = false;
    while (!done)
    {
      done = radio.read( &duino2, sizeof(duino2) );
    }
    radio.stopListening();
    radio.write( &duino1, sizeof(duino1) );
    radio.startListening();
  }
  // end of radio stuff

  // serial print received data 
  Serial.print("duino2.W = ");
  Serial.println(duino2.W);
  Serial.print("duino2.X = ");
  Serial.println(duino2.X);
  Serial.print("duino2.Y = ");
  Serial.println(duino2.Y);
  Serial.print("duino2.Z = ");
  Serial.println(duino2.Z);
  // end of serial printing
}

Sunday, August 14, 2016

Simple NRF24L01 wireless remote

Code for Receiver
#include <"spi .h">
#include "nRF24L01.h"
#include "RF24.h"
int msg[1];
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
int LED1 = 3;
void setup(void){
 Serial.begin(9600);
 radio.begin();
 radio.openReadingPipe(1,pipe);
 radio.startListening();
 pinMode(LED1, OUTPUT);
}
void loop(void){
 if (radio.available()){
   bool done = false;  
   while (!done){
     done = radio.read(msg, 1);    
     Serial.println(msg[0]);
     if (msg[0] == 111){
        delay(10);
        digitalWrite(LED1, HIGH);
     }
     else {digitalWrite(LED1, LOW);}
     delay(10);
}
}
 else{Serial.println("No radio available");}}
============================================
code for transmitter




#include  <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
int msg[1];
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
int SW1 = 7;
void setup(void){
 Serial.begin(9600);
 radio.begin();
 radio.openWritingPipe(pipe);
}
 void loop(void){
 if (digitalRead(SW1) == HIGH){
 msg[0] = 111;
 radio.write(msg, 1);}}

NRF24L01 multi receiver

hardware: 0.1 uf capacitors recommended The connections are laid out in detail in the first link on the prior page. Basically, the pins in the lower right corners of the diagrams above must be connected to the corresponding Arduino pins. VCC must be 3.3V and CE and CSN from the NRF24L01+ connect to pins 7 and 8, respectively, on the Arduino. The IRQ pin is unnecessary in this application. Soldering a 0.1 uf capacitor between the VCC and ground pins of the NRF24L01+ is a good idea.
 
This example is a frivolous game in which the PRX generates a random number and the nodes try to guess the number. Its real purpose is to demonstrate the network in action.
While I think Codebender is fantastic, Please copy the code out of Codebender because the RF24.h library in Codebender appears to be an older version.
First, the code for the PRX primary receiver (hub)
=======================================================
// An example demonstrating the multiceiver capability of the NRF24L01+
// in a star network with one PRX hub and up to six PTX nodes

//This sketch is a modification from a video on the ForceTronics YouTube Channel,
//which code was leveraged from http://maniacbug.github.io/RF24/starping_8pde-example.html
//This sketch is free to the public to use and modify at your own risk

#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/

const int pinCE = 7; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 8; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
RF24 radio(pinCE, pinCSN); // Declare object from nRF24 library (Create your wireless SPI)

//Create up to 6 pipe addresses P0 - P5;  the "LL" is for LongLong type
const uint64_t rAddress[] = {0x7878787878LL, 0xB3B4B5B6F1LL, 0xB3B4B5B6CDLL, 0xB3B4B5B6A3LL, 0xB3B4B5B60FLL, 0xB3B4B5B605LL };

byte daNumber = 0; //The number that the transmitters are trying to guess

void setup()  
{
  randomSeed(analogRead(0)); //create unique seed value for random number generation
  daNumber = (byte)random(11); //Create random number that transmitters have to guess
  Serial.begin(115200);  //start serial to communication
  Serial.print("The number they are trying to guess is: ");
  Serial.println(daNumber); //print the number that they have to guess
  Serial.println();
  radio.begin();  //Start the nRF24 module

  radio.setPALevel(RF24_PA_LOW);  // "short range setting" - increase if you want more range AND have a good power supply
  radio.setChannel(108);          // the higher channels tend to be more "open"

  // Open up to six pipes for PRX to receive data
  radio.openReadingPipe(0,rAddress[0]);
  radio.openReadingPipe(1,rAddress[1]);
  radio.openReadingPipe(2,rAddress[2]);
  radio.openReadingPipe(3,rAddress[3]);
  radio.openReadingPipe(4,rAddress[4]);
  radio.openReadingPipe(5,rAddress[5]);
 
  radio.startListening();                 // Start listening for messages
}

void loop()
{  
    byte pipeNum = 0; //variable to hold which reading pipe sent data
    byte gotByte = 0; //used to store payload from transmit module
   
    while(radio.available(&pipeNum)){ //Check if received data
     radio.read( &gotByte, 1 ); //read one byte of data and store it in gotByte variable
     Serial.print("Received guess from transmitter: ");
     Serial.println(pipeNum + 1); //print which pipe or transmitter this is from
     Serial.print("They guess number: ");
     Serial.println(gotByte); //print payload or the number the transmitter guessed
     if(gotByte != daNumber) { //if true they guessed wrong
      Serial.println("Fail!! Try again.");
     }
     else { //if this is true they guessed right
      if(sendCorrectNumber(pipeNum)) Serial.println("Correct! You're done."); //if true we successfully responded
      else Serial.println("Write failed"); //if true we failed responding
     }
     Serial.println();
    }

   delay(200);  
}

 //This function turns the receiver into a transmitter briefly to tell one of the nRF24s
//in the network that it guessed the right number. Returns true if write to module was
//successful
bool sendCorrectNumber(byte xMitter) {
    bool worked; //variable to track if write was successful
    radio.stopListening(); //Stop listening, start receiving data.
    radio.openWritingPipe(rAddress[xMitter]); //Open writing pipe to the nRF24 that guessed the right number
      // note that this is the same pipe address that was just used for receiving
    if(!radio.write(&daNumber, 1))  worked = false; //write the correct number to the nRF24 module, and check that it was received
    else worked = true; //it was received
    radio.startListening(); //Switch back to a receiver
    return worked;  //return whether write was successful
}

=========================================================
And now the code for the PTX primary transmitters (nodes)

// An example demonstrating the multiceiver capability of the NRF24L01+
// in a star network with one PRX hub and up to six PTX nodes

//This sketch is a modification from a video on the ForceTronics YouTube Channel,

//which code was leveraged from http://maniacbug.github.io/RF24/starping_8pde-example.html

//This sketch is free to the public to use and modify at your own risk


#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+

#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/

#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/

const int pinCE = 7; //This pin is used to set the nRF24 to standby (0) or active mode (1)

const int pinCSN = 8; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out


RF24 radio(pinCE, pinCSN); // Create your nRF24 object or wireless SPI connection

#define WHICH_NODE 2     // must be a number from 1 - 6 identifying the PTX node

const uint64_t wAddress[] = {0x7878787878LL, 0xB3B4B5B6F1LL, 0xB3B4B5B6CDLL, 0xB3B4B5B6A3LL, 0xB3B4B5B60FLL, 0xB3B4B5B605LL};

const uint64_t PTXpipe = wAddress[ WHICH_NODE - 1 ];   // Pulls the address from the above array for this node's pipe

byte counter = 1; //used to count the packets sent

bool done = false; //used to know when to stop sending packets


void setup()

{

  Serial.begin(115200);   //start serial to communicate process

  randomSeed(analogRead(0)); //create unique seed value for random number generation

  radio.begin();            //Start the nRF24 module

  radio.setPALevel(RF24_PA_LOW);  // "short range setting" - increase if you want more range AND have a good power supply
  radio.setChannel(108);          // the higher channels tend to be more "open"

  radio.openReadingPipe(0,PTXpipe);  //open reading or receive pipe

  radio.stopListening(); //go into transmit mode

}

void loop()

{

   if(!done) { //true once you guess the right number

     byte randNumber = (byte)random(11); //generate random guess between 0 and 10

     radio.openWritingPipe(PTXpipe);        //open writing or transmit pipe

     if (!radio.write( &randNumber, 1 )){  //if the write fails let the user know over serial monitor

         Serial.println("Guess delivery failed");    

     }

     else { //if the write was successful

          Serial.print("Success sending guess: ");

          Serial.println(randNumber);

     

        radio.startListening(); //switch to receive mode to see if the guess was right

        unsigned long startTimer = millis(); //start timer, we will wait 200ms

        bool timeout = false;

        while ( !radio.available() && !timeout ) { //run while no receive data and not timed out

          if (millis() - startTimer > 200 ) timeout = true; //timed out

        }

   

        if (timeout) Serial.println("Last guess was wrong, try again"); //no data to receive guess must have been wrong

        else  { //we received something so guess must have been right

          byte daNumber; //variable to store received value

          radio.read( &daNumber,1); //read value

          if(daNumber == randNumber) { //make sure it equals value we just sent, if so we are done

            Serial.println("You guessed right so you are done");

            done = true; //signal to loop that we are done guessing

          }

          else Serial.println("Something went wrong, keep guessing"); //this should never be true, but just in case

        }

        radio.stopListening(); //go back to transmit mode

     }

   }

    delay(1000);
}
=========================================
The #define WHICH_NODE statement needs to be altered for each node. Otherwise, the code is the same.
When running, I suggest powering the PRX first and starting the serial monitor for it. Otherwise you might miss the action!
ENJOY! And please do comment on any way in which this Instructable might be improved.