Go Down

Topic: Please help with a project Im working, using a motion sensor and an arduino mega (Read 405 times) previous topic - next topic

jakemars314

Hello, first things first I know very little about coding and am currently in a class that is asking me to code.  I have a clock that I made using an arduino mega board, an rtc (DS3231) and an LCD screen (DF Robot).  and have the clock up and running.  The instructor now wants us to connect a motion sensor to the board and any time it detects motion it powers the clock on I am going to attach my current code I tried multiple times to place an if else statement within the code but to no avail, like I said I have very little coding experience and our instructor pretty much told us to google how to do it.

Edit: I meatn to include the model number of the PIR it is an HC-SR501

Code: [Select]


#include <Wire.h>
#include "ds3231.h"
#include <LiquidCrystal.h>

LiquidCrystal lcd(8,9,4,5,6,7);

#define BUFF_MAX 128

uint8_t time[8];
char recv[BUFF_MAX];
unsigned int recv_size = 0;
unsigned long prev, interval = 1000;

void setup()
{
    Serial.begin(9600);
    Wire.begin();
    DS3231_init(DS3231_INTCN);
    memset(recv, 0, BUFF_MAX);
    Serial.println("GET time");
    lcd.begin(16, 2);
    lcd.clear();

}

void loop()
{
    char in;
    char tempF[6];
    float temperature;
    char buff[BUFF_MAX];
    unsigned long now = millis();
    struct ts t;
   
    // show time once in a while
    if ((now - prev > interval) && (Serial.available() <= 0)) {
        DS3231_get(&t); //Get time
        parse_cmd("C",1);
        temperature = DS3231_get_treg(); //Get temperature
        dtostrf(temperature, 5, 1, tempF);

        lcd.clear();
        lcd.setCursor(1,0);
       
        lcd.print(t.mday);
       
        printMonth(t.mon);
       
        lcd.print(t.year);
       
        lcd.setCursor(0,1); //Go to second line of the LCD Screen
       if(t.hour > 12) {
    lcd.print(t.hour - 12); }
  else {
    lcd.print(t.hour);}
        lcd.print(":");
        if(t.min<10)
        {
          lcd.print("0");
        }
        lcd.print(t.min);
        lcd.print(":");
        lcd.print("PM");
       
        lcd.print(' ');
        lcd.print(tempF);
        lcd.print((char)223);
        lcd.print("C ");
        prev = now;
    }

   
    if (Serial.available() > 0) {
        in = Serial.read();

        if ((in == 10 || in == 13) && (recv_size > 0)) {
            parse_cmd(recv, recv_size);
            recv_size = 0;
            recv[0] = 0;
        } else if (in < 48 || in > 122) {;       // ignore ~[0-9A-Za-z]
        } else if (recv_size > BUFF_MAX - 2) {   // drop lines that are too long
            // drop
            recv_size = 0;
            recv[0] = 0;
        } else if (recv_size < BUFF_MAX - 2) {
            recv[recv_size] = in;
            recv[recv_size + 1] = 0;
            recv_size += 1;
        }

    }
}

void parse_cmd(char *cmd, int cmdsize)
{
    uint8_t i;
    uint8_t reg_val;
    char buff[BUFF_MAX];
    struct ts t;

    //snprintf(buff, BUFF_MAX, "cmd was '%s' %d\n", cmd, cmdsize);
    //Serial.print(buff);

    // TssmmhhWDDMMYYYY aka set time
    if (cmd[0] == 84 && cmdsize == 16) {
        //T355720619112011
        t.sec = inp2toi(cmd, 1);
        t.min = inp2toi(cmd, 3);
        t.hour = inp2toi(cmd, 5);
        t.wday = inp2toi(cmd, 7);
        t.mday = inp2toi(cmd, 8);
        t.mon = inp2toi(cmd, 10);
        t.year = inp2toi(cmd, 12) * 100 + inp2toi(cmd, 14);
        DS3231_set(t);
        Serial.println("OK");
    } else if (cmd[0] == 49 && cmdsize == 1) {  // "1" get alarm 1
        DS3231_get_a1(&buff[0], 59);
        Serial.println(buff);
    } else if (cmd[0] == 50 && cmdsize == 1) {  // "2" get alarm 1
        DS3231_get_a2(&buff[0], 59);
        Serial.println(buff);
    } else if (cmd[0] == 51 && cmdsize == 1) {  // "3" get aging register
        Serial.print("aging reg is ");
        Serial.println(DS3231_get_aging(), DEC);
    } else if (cmd[0] == 65 && cmdsize == 9) {  // "A" set alarm 1
        DS3231_set_creg(DS3231_INTCN | DS3231_A1IE);
        //ASSMMHHDD
        for (i = 0; i < 4; i++) {
            time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // ss, mm, hh, dd
        }
        byte flags[5] = { 0, 0, 0, 0, 0 };
        DS3231_set_a1(time[0], time[1], time[2], time[3], flags);
        DS3231_get_a1(&buff[0], 59);
        Serial.println(buff);
    } else if (cmd[0] == 66 && cmdsize == 7) {  // "B" Set Alarm 2
        DS3231_set_creg(DS3231_INTCN | DS3231_A2IE);
        //BMMHHDD
        for (i = 0; i < 4; i++) {
            time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // mm, hh, dd
        }
        byte flags[5] = { 0, 0, 0, 0 };
        DS3231_set_a2(time[0], time[1], time[2], flags);
        DS3231_get_a2(&buff[0], 59);
        Serial.println(buff);
    } else if (cmd[0] == 67 && cmdsize == 1) {  // "C" - get temperature register
        Serial.print("temperature reg is ");
        Serial.println(DS3231_get_treg(), DEC);
    } else if (cmd[0] == 68 && cmdsize == 1) {  // "D" - reset status register alarm flags
        reg_val = DS3231_get_sreg();
        reg_val &= B11111100;
        DS3231_set_sreg(reg_val);
    } else if (cmd[0] == 70 && cmdsize == 1) {  // "F" - custom fct
        reg_val = DS3231_get_addr(0x5);
        Serial.print("orig ");
        Serial.print(reg_val,DEC);
        Serial.print("month is ");
        Serial.println(bcdtodec(reg_val & 0x1F),DEC);
    } else if (cmd[0] == 71 && cmdsize == 1) {  // "G" - set aging status register
        DS3231_set_aging(0);
    } else if (cmd[0] == 83 && cmdsize == 1) {  // "S" - get status register
        Serial.print("status reg is ");
        Serial.println(DS3231_get_sreg(), DEC);
    } else {
        Serial.print("unknown command prefix ");
        Serial.println(cmd[0]);
        Serial.println(cmd[0], DEC);
    }
}

void printMonth(int month)
{
  switch(month)
  {
    case 1: lcd.print(" Jan ");break;
    case 2: lcd.print(" Feb ");break;
    case 3: lcd.print(" Mar ");break;
    case 4: lcd.print(" Apr ");break;
    case 5: lcd.print(" May ");break;
    case 6: lcd.print(" Jun ");break;
    case 7: lcd.print(" Jul ");break;
    case 8: lcd.print(" Aug ");break;
    case 9: lcd.print(" Sep ");break;
    case 10: lcd.print(" Oct ");break;
    case 11: lcd.print(" Nov ");break;
    case 12: lcd.print(" Dec ");break;
    default: lcd.print(" Error ");break;
  }
}

pert

You should always put your code directly in the forum post unless it's longer than the forum will allow, in which case it's ok to use an attachment.

I don't see where in the sketch your motion sensor is.

I tried multiple times to place an if else statement within the code but to no avail
Please explain exactly what you mean by "to no avail". If you are getting error messages then post the full content of the error messages using code tags (</> button on the toolbar).

Delta_G

The attached code.

Code: [Select]

#include <Wire.h>
#include "ds3231.h"
#include <LiquidCrystal.h>

LiquidCrystal lcd(8,9,4,5,6,7);

#define BUFF_MAX 128

uint8_t time[8];
char recv[BUFF_MAX];
unsigned int recv_size = 0;
unsigned long prev, interval = 1000;

void setup()
{
    Serial.begin(9600);
    Wire.begin();
    DS3231_init(DS3231_INTCN);
    memset(recv, 0, BUFF_MAX);
    Serial.println("GET time");
    lcd.begin(16, 2);
    lcd.clear();
   
 
}

void loop()
{
    char in;
    char tempF[6];
    float temperature;
    char buff[BUFF_MAX];
    unsigned long now = millis();
    struct ts t;

    // show time once in a while
    if ((now - prev > interval) && (Serial.available() <= 0)) {
        DS3231_get(&t); //Get time
        parse_cmd("C",1);
        temperature = DS3231_get_treg(); //Get temperature
        dtostrf(temperature, 5, 1, tempF);

        lcd.clear();
        lcd.setCursor(1,0);
       
        lcd.print(t.mday);
       
        printMonth(t.mon);
       
        lcd.print(t.year);
       
        lcd.setCursor(0,1); //Go to second line of the LCD Screen
        lcd.print(t.hour);
        lcd.print(":");
        if(t.min<10)
        {
          lcd.print("0");
        }
        lcd.print(t.min);
        lcd.print(":");
        if(t.sec<10)
        {
          lcd.print("0");
        }
        lcd.print(t.sec);
       
        lcd.print(' ');
        lcd.print(tempF);
        lcd.print((char)223);
        lcd.print("C ");
        prev = now;
    }

   
    if (Serial.available() > 0) {
        in = Serial.read();

        if ((in == 10 || in == 13) && (recv_size > 0)) {
            parse_cmd(recv, recv_size);
            recv_size = 0;
            recv[0] = 0;
        } else if (in < 48 || in > 122) {;       // ignore ~[0-9A-Za-z]
        } else if (recv_size > BUFF_MAX - 2) {   // drop lines that are too long
            // drop
            recv_size = 0;
            recv[0] = 0;
        } else if (recv_size < BUFF_MAX - 2) {
            recv[recv_size] = in;
            recv[recv_size + 1] = 0;
            recv_size += 1;
        }

    }
}

void parse_cmd(char *cmd, int cmdsize)
{
    uint8_t i;
    uint8_t reg_val;
    char buff[BUFF_MAX];
    struct ts t;

    //snprintf(buff, BUFF_MAX, "cmd was '%s' %d\n", cmd, cmdsize);
    //Serial.print(buff);

    // TssmmhhWDDMMYYYY aka set time
    if (cmd[0] == 84 && cmdsize == 16) {
        //T355720619112011
        t.sec = inp2toi(cmd, 1);
        t.min = inp2toi(cmd, 3);
        t.hour = inp2toi(cmd, 5);
        t.wday = inp2toi(cmd, 7);
        t.mday = inp2toi(cmd, 8);
        t.mon = inp2toi(cmd, 10);
        t.year = inp2toi(cmd, 12) * 100 + inp2toi(cmd, 14);
        DS3231_set(t);
        Serial.println("OK");
    } else if (cmd[0] == 49 && cmdsize == 1) {  // "1" get alarm 1
        DS3231_get_a1(&buff[0], 59);
        Serial.println(buff);
    } else if (cmd[0] == 50 && cmdsize == 1) {  // "2" get alarm 1
        DS3231_get_a2(&buff[0], 59);
        Serial.println(buff);
    } else if (cmd[0] == 51 && cmdsize == 1) {  // "3" get aging register
        Serial.print("aging reg is ");
        Serial.println(DS3231_get_aging(), DEC);
    } else if (cmd[0] == 65 && cmdsize == 9) {  // "A" set alarm 1
        DS3231_set_creg(DS3231_INTCN | DS3231_A1IE);
        //ASSMMHHDD
        for (i = 0; i < 4; i++) {
            time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // ss, mm, hh, dd
        }
        byte flags[5] = { 0, 0, 0, 0, 0 };
        DS3231_set_a1(time[0], time[1], time[2], time[3], flags);
        DS3231_get_a1(&buff[0], 59);
        Serial.println(buff);
    } else if (cmd[0] == 66 && cmdsize == 7) {  // "B" Set Alarm 2
        DS3231_set_creg(DS3231_INTCN | DS3231_A2IE);
        //BMMHHDD
        for (i = 0; i < 4; i++) {
            time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // mm, hh, dd
        }
        byte flags[5] = { 0, 0, 0, 0 };
        DS3231_set_a2(time[0], time[1], time[2], flags);
        DS3231_get_a2(&buff[0], 59);
        Serial.println(buff);
    } else if (cmd[0] == 67 && cmdsize == 1) {  // "C" - get temperature register
        Serial.print("temperature reg is ");
        Serial.println(DS3231_get_treg(), DEC);
    } else if (cmd[0] == 68 && cmdsize == 1) {  // "D" - reset status register alarm flags
        reg_val = DS3231_get_sreg();
        reg_val &= B11111100;
        DS3231_set_sreg(reg_val);
    } else if (cmd[0] == 70 && cmdsize == 1) {  // "F" - custom fct
        reg_val = DS3231_get_addr(0x5);
        Serial.print("orig ");
        Serial.print(reg_val,DEC);
        Serial.print("month is ");
        Serial.println(bcdtodec(reg_val & 0x1F),DEC);
    } else if (cmd[0] == 71 && cmdsize == 1) {  // "G" - set aging status register
        DS3231_set_aging(0);
    } else if (cmd[0] == 83 && cmdsize == 1) {  // "S" - get status register
        Serial.print("status reg is ");
        Serial.println(DS3231_get_sreg(), DEC);
    } else {
        Serial.print("unknown command prefix ");
        Serial.println(cmd[0]);
        Serial.println(cmd[0], DEC);
    }
}

void printMonth(int month)
{
  switch(month)
  {
    case 1: lcd.print(" Jan ");break;
    case 2: lcd.print(" Feb ");break;
    case 3: lcd.print(" Mar ");break;
    case 4: lcd.print(" Apr ");break;
    case 5: lcd.print(" May ");break;
    case 6: lcd.print(" Jun ");break;
    case 7: lcd.print(" Jul ");break;
    case 8: lcd.print(" Aug ");break;
    case 9: lcd.print(" Sep ");break;
    case 10: lcd.print(" Oct ");break;
    case 11: lcd.print(" Nov ");break;
    case 12: lcd.print(" Dec ");break;
    default: lcd.print(" Error ");break;
  }
}
If at first you don't succeed, up - home - sudo - enter.

jakemars314

The code I attached is the code without the if else statement within it because every way I have tried to place it has either caused my clock to stop functioning properly, does anyone have suggestions on how I may need to write the code or a website thats reliable that could help me with this?  the if else I used is below
I put the original code within the if statement,

Again my coding experience is very limited I apologize if my question is unclear or inadequate I am not sure what I need to get this thing working, and am hopefully asking the question in an understandable manner thank you for trying to help me.

Code: [Select]

int clockPin = 24;                // choose the pin for the clock
int inputPin = 2;               // choose the input pin (for PIR sensor)
int pirState = LOW;             // we start, assuming no motion detected
int val = 0;                    // variable for reading the pin status

void setup() {
pinMode(clockPin, OUTPUT);      // declare clock as output
pinMode(inputPin, INPUT);     // declare sensor as input

Serial.begin(9600);
}

void loop(){
val = digitalRead(inputPin);  // read input value
if (val == HIGH) {            // check if the input is HIGH
  digitalWrite(clockPin, HIGH);  // turn clock ON
  if (pirState == LOW) {
   
    Serial.println("Motion detected!");
   
    pirState = HIGH;
  }
} else {
  digitalWrite(clockPin, LOW); // turn Clock OFF
  if (pirState == HIGH){
   
    Serial.println("Motion ended!");
   
    pirState = LOW;
  }
}
}

pert

Please always do a Tools > Auto Format on your code before posting it. This will make it easier for you to spot bugs and make it easier for us to read.

Do you see the expected results in the Serial Monitor when you run the above code?

jakemars314

no when I put this code in and place my code within the if function my clock doesnt display anything the screen goes blank, I've waited a few minutes to see if the PIR needs to initialize ( the website for the items states it has a 1 minute initialization process) but even after that it doesnt seem to react to motion.

pert

and place my code within the if function
Don't do that. You need to first verify that the motion sensor is working before even thinking about putting any clock code in. Try this code and don't add anything to it until it's working:
Code: [Select]
int PIRsensorPin = 2;               // choose the input pin (for PIR sensor)

void setup() {
  pinMode(PIRsensorPin, INPUT);     // declare sensor as input
  Serial.begin(9600);
}

void loop() {
  if (digitalRead(PIRsensorPin) == HIGH) {
    Serial.println("Motion detected!");
  }
  else {
    Serial.println("Motion ended!");
  }
}

jakemars314

ok, after I upload this code what should the motion sensor cause on detection?

pert

Tools > Serial Monitor
Set the menu at the bottom right corner of the Serial Monitor window to 9600.
You should see "Motion detected!" printed over and over again after motion is detected until there has been no motion for longer than the timeout duration, then it will change to printing "Motion ended!" over and over again until it detects motion again.

jakemars314

OK I have motion detected, now how do I implement the code for the motion sensor within my code? thank you for your help.

Edit: I have gotten the clock to display and then clear with and without motion, but the clock stays powered, does anyone know where in my code I could have the clock entirely power down. 

Code: [Select]

int PIRsensorPin = 24;               // choose the input pin (for PIR sensor)

void setup2() {
  pinMode(PIRsensorPin, INPUT);     // declare sensor as input
  Serial.begin(9600);
}

void loop2() {
  if (digitalRead(PIRsensorPin) == HIGH) {
    Serial.println("Motion detected!");
    char in;
    char tempF[6];
    float temperature;
    char buff[BUFF_MAX];
    unsigned long now = millis();
    struct ts t;
   
    // show time once in a while
    if ((now - prev > interval) && (Serial.available() <= 0)) {
        DS3231_get(&t); //Get time
     
        temperature = DS3231_get_treg(); //Get temperature
        dtostrf(temperature, 5, 1, tempF);

        lcd.clear();
        lcd.setCursor(1,0);
       
        lcd.print(t.mday);
       
        printMonth(t.mon);
       
        lcd.print(t.year);
       
        lcd.setCursor(0,1); //Go to second line of the LCD Screen
       if(t.hour > 12) {
    lcd.print(t.hour - 12); }
  else {
    lcd.print(t.hour);}
        lcd.print(":");
        if(t.min<10)
        {
          lcd.print("0");
        }
        lcd.print(t.min);
        lcd.print(":");
        lcd.print("PM");
       
        lcd.print(' ');
        lcd.print(tempF);
        lcd.print((char)223);
        lcd.print("C ");
        prev = now;
    }

   
    if (Serial.available() > 0) {
        in = Serial.read();

        if ((in == 10 || in == 13) && (recv_size > 0)) {
            parse_cmd(recv, recv_size);
            recv_size = 0;
            recv[0] = 0;
        } else if (in < 48 || in > 122) {;       // ignore ~[0-9A-Za-z]
        } else if (recv_size > BUFF_MAX - 2) {   // drop lines that are too long
            // drop
            recv_size = 0;
            recv[0] = 0;
        } else if (recv_size < BUFF_MAX - 2) {
            recv[recv_size] = in;
            recv[recv_size + 1] = 0;
            recv_size += 1;
         }

  }
  }
    else {
    Serial.println("Motion ended!");
    lcd.clear();
  }
}

cattledog

Quote
but the clock stays powered, does anyone know where in my code I could have the clock entirely power down. 
What was clockPin connected to, and what happened when you wrote it LOW?

Are you trying to turn off the display and the backlight, or are trying to turn off Vcc to the rtc and have it running on backup battery power?


jakemars314

The screen stays on but goes blank, I would like for the screen itself to shutoff completely, clockpin is connected to the motion sensor.

cattledog

Quote
The screen stays on but goes blank, I would like for the screen itself to shutoff completely
The backlight for the lcd should be wired through pin 15(+5v) and 16(gnd) of the lcd. There should be at least 220 ohms resistance in that circuit, and this resistance may be on the lcd module (R8) or it may be external in your circuit.

The idea is to keep the constant current to the led at 20ma or less. This is what is recommended for constant output from an individual Arduino pin, although the rated maximum is 40ma.

If the current is less than 20 ma, you should be able to switch the backlight on and off directly with an output pin. Bring the line from lcd pin 15 to an Arduino digital pin and write it HIGH or LOW.

pert

Please always do a Tools > Auto Format on your code before posting it. This will make it easier for you to spot bugs and make it easier for us to read.

Explain exactly what you mean by "setting a time for the screen to display".

Where did this setup2(), loop2() thing come from? You need to post your full sketch.


Go Up