Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. OLED not wroking for me

OLED not wroking for me

Scheduled Pinned Locked Moved Development
9 Posts 2 Posters 1.3k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Kai BepperlingK Offline
    Kai BepperlingK Offline
    Kai Bepperling
    wrote on last edited by
    #1

    I am trying to get an 128x32 OLED (I2C) working with MySensors 2.2.0

    When i include the lib (regardless if i'm trying the Adafruit lib, U8g2lib or the shorted lib from https://forum.mysensors.org/topic/2360/temperature-humidity-node-with-oled-display/5) my sensor is not working anymore. I dont need to use the lib, including is enough.

    I'm using an NRF24L01+ with an Arduino Nano and here are my includes

    #define MY_DEBUG       //Comment out in production mode
    #define MY_RADIO_NRF24 //use the NRF24L01+ module
    #include <MySensors.h>
    #include <Arduino.h>      //need to be included, cause the file is moved to a .cpp file
    #include <MotionSensor.h> //MotionSensorLib
    //Include and Set Up BatteryMeter Library
    #include <BatteryMeter.h>
    #define USE_OLED
    #ifdef USE_OLED
    // includes for OLED 128x32 and 128x64 support
    #include <SSD1306_text.h>
    //SSD1306_text oled;
    
    #endif
    
    void setup(){
    ...
    }
    
    mfalkviddM 1 Reply Last reply
    0
    • Kai BepperlingK Kai Bepperling

      I am trying to get an 128x32 OLED (I2C) working with MySensors 2.2.0

      When i include the lib (regardless if i'm trying the Adafruit lib, U8g2lib or the shorted lib from https://forum.mysensors.org/topic/2360/temperature-humidity-node-with-oled-display/5) my sensor is not working anymore. I dont need to use the lib, including is enough.

      I'm using an NRF24L01+ with an Arduino Nano and here are my includes

      #define MY_DEBUG       //Comment out in production mode
      #define MY_RADIO_NRF24 //use the NRF24L01+ module
      #include <MySensors.h>
      #include <Arduino.h>      //need to be included, cause the file is moved to a .cpp file
      #include <MotionSensor.h> //MotionSensorLib
      //Include and Set Up BatteryMeter Library
      #include <BatteryMeter.h>
      #define USE_OLED
      #ifdef USE_OLED
      // includes for OLED 128x32 and 128x64 support
      #include <SSD1306_text.h>
      //SSD1306_text oled;
      
      #endif
      
      void setup(){
      ...
      }
      
      mfalkviddM Offline
      mfalkviddM Offline
      mfalkvidd
      Mod
      wrote on last edited by
      #2

      @kai-bepperling could you clarify what you mean by "my sensor is not working"? Do you get a compilation error? Or strange readings? Something else?

      1 Reply Last reply
      0
      • Kai BepperlingK Offline
        Kai BepperlingK Offline
        Kai Bepperling
        wrote on last edited by Kai Bepperling
        #3

        Ah damn it. I was sure i posted the Log...

        At the beginning everything initializes fine like:

        16 MCO:BGN:INIT NODE,CP=RNNNA---,VER=2.2.0
        25 TSM:INIT
        26 TSF:WUR:MS=0
        33 TSM:INIT:TSP OK
        35 TSF:SID:OK,ID=4
        37 TSM:FPAR
        73 TSF:MSG:SEND,4-4-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
        637 TSF:MSG:READ,0-0-4,s=255,c=3,t=8,pt=1,l=1,sg=0:0
        643 TSF:MSG:FPAR OK,ID=0,D=1
        985 TSF:MSG:READ,3-3-4,s=255,c=3,t=8,pt=1,l=1,sg=0:1
        2080 TSM:FPAR:OK
        2081 TSM:ID
        2082 TSM:ID:OK
        2084 TSM:UPL
        2087 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
        2098 TSF:MSG:READ,0-0-4,s=255,c=3,t=25,pt=1,l=1,sg=0:1
        2102 TSF:MSG:PONG RECV,HP=1
        2105 TSM:UPL:OK
        2106 TSM:READY:ID=4,PAR=0,DIS=1
        2111 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=OK:0100
        2118 TSF:MSG:READ,0-0-4,s=255,c=3,t=15,pt=6,l=2,sg=0:0100
        2127 TSF:MSG:SEND,4-4-0-0,s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=OK:2.2.0
        2136 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=OK:0
        2147 TSF:MSG:READ,0-0-4,s=255,c=3,t=6,pt=0,l=1,sg=0:M
        2154 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=11,pt=0,l=5,sg=0,ft=0,st=OK:RooDe
        2162 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=12,pt=0,l=6,sg=0,ft=0,st=OK:0.9.3b
        2170 TSF:MSG:SEND,4-4-0-0,s=0,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
        2179 TSF:MSG:SEND,4-4-0-0,s=1,c=0,t=36,pt=0,l=0,sg=0,ft=0,st=OK:
        2186 TSF:MSG:SEND,4-4-0-0,s=3,c=0,t=36,pt=0,l=0,sg=0,ft=0,st=OK:
        2192 MCO:REG:REQ
        2195 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=OK:2
        2202 TSF:MSG:READ,0-0-4,s=255,c=3,t=27,pt=1,l=1,sg=0:1
        2206 MCO:PIM:NODE REG=1
        2209 MCO:BGN:STP
        

        Then i calibrate my IR Sensors (Analog pins 7 and 8) which fails because:

        1
        1
        2
        11
        11
        15
        15
        43
        47
        48
        56
        72
        79
        95
        111
        125
        New threshold is: 19327
        

        i am just calculating an average... After that the sensor does not detect movement through both sensors which results in not sending anything or i just getting a TNR.

        When reading values like IRR:770
        IRC:376
        wihtout the included library the sensor will send a new state. This is a very strange behavior.

        mfalkviddM 1 Reply Last reply
        1
        • Kai BepperlingK Kai Bepperling

          Ah damn it. I was sure i posted the Log...

          At the beginning everything initializes fine like:

          16 MCO:BGN:INIT NODE,CP=RNNNA---,VER=2.2.0
          25 TSM:INIT
          26 TSF:WUR:MS=0
          33 TSM:INIT:TSP OK
          35 TSF:SID:OK,ID=4
          37 TSM:FPAR
          73 TSF:MSG:SEND,4-4-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
          637 TSF:MSG:READ,0-0-4,s=255,c=3,t=8,pt=1,l=1,sg=0:0
          643 TSF:MSG:FPAR OK,ID=0,D=1
          985 TSF:MSG:READ,3-3-4,s=255,c=3,t=8,pt=1,l=1,sg=0:1
          2080 TSM:FPAR:OK
          2081 TSM:ID
          2082 TSM:ID:OK
          2084 TSM:UPL
          2087 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=24,pt=1,l=1,sg=0,ft=0,st=OK:1
          2098 TSF:MSG:READ,0-0-4,s=255,c=3,t=25,pt=1,l=1,sg=0:1
          2102 TSF:MSG:PONG RECV,HP=1
          2105 TSM:UPL:OK
          2106 TSM:READY:ID=4,PAR=0,DIS=1
          2111 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=15,pt=6,l=2,sg=0,ft=0,st=OK:0100
          2118 TSF:MSG:READ,0-0-4,s=255,c=3,t=15,pt=6,l=2,sg=0:0100
          2127 TSF:MSG:SEND,4-4-0-0,s=255,c=0,t=17,pt=0,l=5,sg=0,ft=0,st=OK:2.2.0
          2136 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=6,pt=1,l=1,sg=0,ft=0,st=OK:0
          2147 TSF:MSG:READ,0-0-4,s=255,c=3,t=6,pt=0,l=1,sg=0:M
          2154 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=11,pt=0,l=5,sg=0,ft=0,st=OK:RooDe
          2162 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=12,pt=0,l=6,sg=0,ft=0,st=OK:0.9.3b
          2170 TSF:MSG:SEND,4-4-0-0,s=0,c=0,t=3,pt=0,l=0,sg=0,ft=0,st=OK:
          2179 TSF:MSG:SEND,4-4-0-0,s=1,c=0,t=36,pt=0,l=0,sg=0,ft=0,st=OK:
          2186 TSF:MSG:SEND,4-4-0-0,s=3,c=0,t=36,pt=0,l=0,sg=0,ft=0,st=OK:
          2192 MCO:REG:REQ
          2195 TSF:MSG:SEND,4-4-0-0,s=255,c=3,t=26,pt=1,l=1,sg=0,ft=0,st=OK:2
          2202 TSF:MSG:READ,0-0-4,s=255,c=3,t=27,pt=1,l=1,sg=0:1
          2206 MCO:PIM:NODE REG=1
          2209 MCO:BGN:STP
          

          Then i calibrate my IR Sensors (Analog pins 7 and 8) which fails because:

          1
          1
          2
          11
          11
          15
          15
          43
          47
          48
          56
          72
          79
          95
          111
          125
          New threshold is: 19327
          

          i am just calculating an average... After that the sensor does not detect movement through both sensors which results in not sending anything or i just getting a TNR.

          When reading values like IRR:770
          IRC:376
          wihtout the included library the sensor will send a new state. This is a very strange behavior.

          mfalkviddM Offline
          mfalkviddM Offline
          mfalkvidd
          Mod
          wrote on last edited by
          #4

          @kai-bepperling how much ram is available? (This is showsn at end of compilation if you press ctrl+r)
          Would you mind posting your entire sketch?

          1 Reply Last reply
          0
          • Kai BepperlingK Offline
            Kai BepperlingK Offline
            Kai Bepperling
            wrote on last edited by
            #5

            I'm using PlatformIO but i think this is what you asked for:

            Program:   15728 bytes (48.0% Full)
            (.text + .data + .bootloader)
            
            Data:        854 bytes (41.7% Full)
            (.data + .bss + .noinit)
            

            roode.cpp

            /*  Room Presence Detection - Microcontroller projects@H-BRS WS16/17
                                  Kai Bepperling
            
            */
            // MySensorStuff
            #define MY_DEBUG       //Comment out in production mode
            #define MY_RADIO_NRF24 //use the NRF24L01+ module
            #include <MySensors.h>
            #include <Arduino.h>      //need to be included, cause the file is moved to a .cpp file
            #include <MotionSensor.h> //MotionSensorLib
            //Include and Set Up BatteryMeter Library
            #include <BatteryMeter.h>
            /*
              Version numbers
              Please update frequently
            */
            #define ROODE_VERSION "0.9.3b"
            // #define MYSENSORS_VERSION "2.2.0"
            
            /*Feature selection
              * USE_OLED for OLED 128x32 support
              * USE_BATTERY when powering the controller with an Lithium battery
              * CALIBRATION for calibrating the IR Sensors on startup
            */
            // #define USE_OLED
            // #define USE_BATTERY
            #define CALIBRATION //enables calibration of the irsensors and motion sensor initializing
            
            // battery setup
            #ifdef USE_BATTERY
            BatteryMeter battery(3);                            //BatteryMeter instance
            #define CHILD_ID_BATTERY 2                          //MySensors Battery child ID
            #define BATTERY_FULL 4.2                            // a 18650 lithium ion battery usually give 4.2V when full
            #define BATTERY_ZERO 3.5                            // 2.4V limit for 328p at 16MHz. 1.9V, limit for nrf24l01 without
            MyMessage voltage_msg(CHILD_ID_BATTERY, V_VOLTAGE); //MySensors battery voltage message instance
            #endif
            
            /* MySensors Message types and default settings */
            unsigned long SLEEP_TIME = 0; //sleep forever
            #define CHILD_ID_R 0
            #define CHILD_ID_PC 1
            #define CHILD_ID_THR 3
            MyMessage msg(CHILD_ID_R, V_STATUS);    //room on/off child
            MyMessage pcMsg(CHILD_ID_PC, V_TEXT);   //people counter child
            MyMessage thrMsg(CHILD_ID_THR, V_TEXT); //Threshold child
            
            /* Motion Sensor setup*/
            #define DIGITAL_INPUT_SENSOR 2 // motion sensor digital pin (2 or 3 because just those pins are interrupt pins)
            MotionSensor motion(DIGITAL_INPUT_SENSOR);
            // int pirState = LOW; // we start, assuming no motion detected
            // int val = 0;        // variable for reading the pin status
            // int MotionInit = 2; // set init time in seconds. Should be set to 60s in production mode!
            
            /* IR Sensor setup*/
            #define ANALOG_IR_SENSORR 0 //IR Room Analog Pin
            #define ANALOG_IR_SENSORC 2 //IR Corridor Analog Pin
            #define IR_D_R 7            //IR Sensor Digital Pin for Room - EN Pin
            #define IR_D_C 8            //IR Sensor Digital Pin for Corridor - EN Pin
            #define LTIME 10000         // loop time (should not be lower than 8 seconds)
            #define MTIME 800           // measuring/person
            #define CALIBRATION_VAL 500 //read 500 values (250 from each sensor)
            //#define IR_BOOT 30 // Not needed for the new sensors caused by the enable pin
            
            /* OLED setup 
              For now only the OLED 128x32 monochrom displays are supported without modification
            */
            #ifdef USE_OLED
            // includes for OLED 128x32 and 128x64 support
            #include <SSD1306_text.h>
            SSD1306_text oled;
            
            #endif
            
            // some needed var declarations
            int irrVal = 0;      //analog value store for the room sensor
            int ircVal = 0;      //analog value store for the corridor sensor
            int threshold = 160; //if CALIBRATION is not defined, this threshold is used (okay for a 80cm doorway using reflection foil)
            int inout = -1;      //if inout== 0 -> out; if inout == 1 --> in; THIS STATE WILL BE SENT!
            int peopleCount = 0; //default state: nobody is inside the room
            
            // function prototypes
            // int checkMotion();
            void irSensor();
            int calibration();
            void send();
            
            void setup()
            {
              #ifdef USE_OLED
              // display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
              // display.display();
              oled.init();
              oled.clear();
              // oled.setTextSize(2);
              // oled.setCursor(0, 0);
              // oled.println("### Roode ###");
              // oled.setCursor(0,15);
              // oled.print("RooDe: ");
              // oled.print(ROODE_VERSION);
              // oled.println("MySensors: 2.2.0");
              #endif
            
              Serial.println("##### RooDe Presence Detection System #####");
            
              //Corridor Sensor Enable PIN
              pinMode(IR_D_C, OUTPUT);
            
              //Room Sensor Voltage Enable PIN
              pinMode(IR_D_R, OUTPUT);
            
              //Motion Sensor
              pinMode(DIGITAL_INPUT_SENSOR, INPUT); // declare motionsensor as input
            
            #ifdef CALIBRATION
              // Serial.println("#### initialize the motion sensor ####");
              //Sensor intialisation
              // for (int i = 0; i < MotionInit; i++) {
              //   wait(1000);
              // }
              motion.Setup(10);
              // Serial.println("#### motion sensor initialized ####");
            
              Serial.println("#### calibrate the ir sensors ####");
              threshold = calibration();
              Serial.print("New threshold is: ");
              Serial.println(threshold);
              send(thrMsg.set(threshold));
              Serial.println("#### calibration done ####");
            #endif
            
              Serial.println("#### Setting the PresenceCounter and Status to OUT (0) ####");
              send(msg.set(0));   //Setting presence status to 0
              send(pcMsg.set(0)); //Setting the people counter to 0
            }
            
            void presentation()
            {
              sendSketchInfo("RooDe", ROODE_VERSION);
              present(CHILD_ID_R, S_BINARY);
              present(CHILD_ID_PC, S_INFO);
            #ifdef USE_BATTERY
              present(CHILD_ID_BATTERY, S_CUSTOM);
            #endif
              present(CHILD_ID_THR, S_INFO);
            }
            
            void loop()
            {
            
              // Sleep until interrupt comes in on motion sensor. Send never an update
            
              if (motion.checkMotion() == LOW)
              {
                irSensor();
                digitalWrite(IR_D_R, LOW);
                wait(1);
                digitalWrite(IR_D_C, LOW);
                sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), RISING, SLEEP_TIME);
                irSensor();
                while (motion.checkMotion() != LOW)
                {
                  irSensor();
                }
              }
            }
            
            // int checkMotion() {
            //   //Motion Sensor
            //   val = digitalRead(DIGITAL_INPUT_SENSOR);  // read input value
            //   if (val == HIGH) {            // check if the input is HIGH
            //
            //     if (pirState == LOW) {      // check if the pir status is LOW
            // #ifdef MY_DEBUG
            //       Serial.println("Motion detected");
            // #endif
            //       pirState = HIGH;          // set pir status to HIGH
            //     }
            //   } else {
            //     if (pirState == HIGH) {     //check if the pir status is HIGH
            // #ifdef MY_DEBUG
            //       Serial.println("No Motion");
            // #endif
            //       pirState = LOW;           // set the pir status to LOW
            //     }
            //   }
            //   return pirState;
            // }
            
            void irSensor()
            {
              int starttime = millis();
              int endtime = starttime;
            
              while ((endtime - starttime) <= LTIME) // do this loop for up to 5000mS
              {
                // turn both sensors on
                digitalWrite(IR_D_R, HIGH);
                wait(1);
                digitalWrite(IR_D_C, HIGH);
                wait(5);
                inout = -1;
            
                irrVal = analogRead(ANALOG_IR_SENSORR);
                wait(10);
                ircVal = analogRead(ANALOG_IR_SENSORC);
            
            #ifdef MY_DEBUG
                Serial.print("IRR:");
                Serial.println(irrVal);
                Serial.print("IRC:");
                Serial.println(ircVal);
            #endif
                if (irrVal > threshold && ircVal < threshold && inout != 1)
                {
                  int startR = millis();
                  int endR = startR;
                  while ((endR - startR) <= MTIME)
                  {
                    irrVal = analogRead(ANALOG_IR_SENSORR);
                    wait(10);
                    ircVal = analogRead(ANALOG_IR_SENSORC);
                    if (ircVal > threshold && irrVal > threshold)
                    {
            #ifdef MY_DEBUG
                      Serial.print("In Loop IRR: ");
                      Serial.println(irrVal);
                      Serial.print("In Loop IRC: ");
                      Serial.println(ircVal);
                      Serial.print("Delay Time: ");
                      Serial.println(MTIME - (endR - startR));
            #endif
                      while (irrVal > threshold || ircVal > threshold)
                      {
                        irrVal = analogRead(ANALOG_IR_SENSORR);
                        wait(10);
                        ircVal = analogRead(ANALOG_IR_SENSORC);
                        if (ircVal > threshold && irrVal < threshold)
                        {
                          // turn both sensors off
                          digitalWrite(IR_D_R, LOW);
                          wait(1);
                          digitalWrite(IR_D_C, LOW);
                          inout = 0;
                          send();
                          break;
                        }
                        wait(11);
                      }
            
                      if (inout == 0)
                      {
                        wait(150);
                        ircVal = 0;
                        endR = millis();
                        starttime = millis();
                        endtime = starttime;
                        break;
                      }
                    }
                    else
                    {
                      wait(1);
                      endR = millis();
                    }
                  }
                }
                else
                {
                  endtime = millis();
                }
            
                if (ircVal > threshold && irrVal < threshold && inout != 0)
                {
                  int startC = millis();
                  int endC = startC;
                  while ((endC - startC) <= MTIME)
                  {
                    ircVal = analogRead(ANALOG_IR_SENSORC);
                    wait(10);
                    irrVal = analogRead(ANALOG_IR_SENSORR);
                    if (irrVal > threshold && ircVal > threshold)
                    {
            #ifdef MY_DEBUG
                      Serial.print("In Loop IRC: ");
                      Serial.println(ircVal);
                      Serial.print("In Loop IRR: ");
                      Serial.println(irrVal);
                      Serial.print("Delay Time: ");
                      Serial.println(MTIME - (endC - startC));
            #endif
                      while (irrVal > threshold || ircVal > threshold)
                      {
                        irrVal = analogRead(ANALOG_IR_SENSORR);
                        wait(10);
                        ircVal = analogRead(ANALOG_IR_SENSORC);
                        if (irrVal > threshold && ircVal < threshold)
                        {
                          // turn both sensors off
                          digitalWrite(IR_D_R, LOW);
                          wait(1);
                          digitalWrite(IR_D_C, LOW);
                          inout = 1;
                          send();
                          break;
                        }
                        wait(11);
                      }
            
                      if (inout == 1)
                      {
                        wait(150);
                        irrVal = 0;
                        endC = millis();
                        starttime = millis();
                        endtime = starttime;
                        break;
                      }
                    }
                    else
                    {
                      wait(11);
                      endC = millis();
                    }
                  }
                }
                else
                {
                  endtime = millis();
                }
                wait(11);
              }
            }
            
            void send()
            {
              if (inout == 1)
              {
                peopleCount++;
                send(msg.set(inout));
                wait(30);
                send(pcMsg.set(peopleCount));
              }
              else if (inout == 0)
              {
                if (peopleCount > 0)
                {
                  peopleCount--;
                }
                if (peopleCount == 0)
                {
                  send(msg.set(inout));
                }
                wait(30);
                send(pcMsg.set(peopleCount));
              }
            
            #ifdef USE_BATTERY
              float voltage = battery.checkBatteryLevel();
              send(voltage_msg.set(voltage, 3)); // redVcc returns millivolts. Set wants volts and how many decimals (3 in our case)
              sendBatteryLevel(round((voltage - BATTERY_ZERO) * 100.0 / (BATTERY_FULL - BATTERY_ZERO)));
            #endif
            }
            
            int calibration()
            {
            
              digitalWrite(IR_D_C, HIGH);
              digitalWrite(IR_D_R, HIGH);
              delay(100);
              int distances[CALIBRATION_VAL];
              int max = 0;
              for (int m = 0; m < CALIBRATION_VAL; m = m + 2)
              {
                delay(8);
                irrVal = analogRead(ANALOG_IR_SENSORR);
                delay(8);
                ircVal = analogRead(ANALOG_IR_SENSORC);
            
                //calculate the max without jumps for the room sensor
                if ((irrVal >= max && (irrVal - max) < 30) || irrVal - max == irrVal)
                {
                  Serial.println(irrVal);
                  max = irrVal;
                  distances[m] = irrVal;
                }
                else
                {
                  distances[m] = 0;
                }
            
                //calculate the max without jumps for the corridor sensor
                if (((ircVal >= max) && ((ircVal - max) < 30)) || ((ircVal - max) == ircVal))
                {
                  Serial.println(ircVal);
                  max = ircVal;
                  distances[m + 1] = ircVal;
                }
                else
                {
                  distances[m + 1] = 0;
                }
              }
            
              // shutdown both sensors
              digitalWrite(IR_D_C, LOW);
              digitalWrite(IR_D_R, LOW);
              max = 0;
              //calculate the absolute max value to determine the new threshold
              for (int i = 0; i < CALIBRATION_VAL; i++)
              {
                if (distances[i] >= max)
                {
                  max = distances[i];
                }
              }
              return max + 30; //add 30 to be super safe
            }
            
            /*
              - Not sure if this function ever will be used... But good idea to have this as backup
              - Tests will be show more about RAM problems
            */
            int freeRam()
            {
              extern int __heap_start, *__brkval;
              int v;
              return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
            }
            
            
            mfalkviddM 1 Reply Last reply
            0
            • Kai BepperlingK Kai Bepperling

              I'm using PlatformIO but i think this is what you asked for:

              Program:   15728 bytes (48.0% Full)
              (.text + .data + .bootloader)
              
              Data:        854 bytes (41.7% Full)
              (.data + .bss + .noinit)
              

              roode.cpp

              /*  Room Presence Detection - Microcontroller projects@H-BRS WS16/17
                                    Kai Bepperling
              
              */
              // MySensorStuff
              #define MY_DEBUG       //Comment out in production mode
              #define MY_RADIO_NRF24 //use the NRF24L01+ module
              #include <MySensors.h>
              #include <Arduino.h>      //need to be included, cause the file is moved to a .cpp file
              #include <MotionSensor.h> //MotionSensorLib
              //Include and Set Up BatteryMeter Library
              #include <BatteryMeter.h>
              /*
                Version numbers
                Please update frequently
              */
              #define ROODE_VERSION "0.9.3b"
              // #define MYSENSORS_VERSION "2.2.0"
              
              /*Feature selection
                * USE_OLED for OLED 128x32 support
                * USE_BATTERY when powering the controller with an Lithium battery
                * CALIBRATION for calibrating the IR Sensors on startup
              */
              // #define USE_OLED
              // #define USE_BATTERY
              #define CALIBRATION //enables calibration of the irsensors and motion sensor initializing
              
              // battery setup
              #ifdef USE_BATTERY
              BatteryMeter battery(3);                            //BatteryMeter instance
              #define CHILD_ID_BATTERY 2                          //MySensors Battery child ID
              #define BATTERY_FULL 4.2                            // a 18650 lithium ion battery usually give 4.2V when full
              #define BATTERY_ZERO 3.5                            // 2.4V limit for 328p at 16MHz. 1.9V, limit for nrf24l01 without
              MyMessage voltage_msg(CHILD_ID_BATTERY, V_VOLTAGE); //MySensors battery voltage message instance
              #endif
              
              /* MySensors Message types and default settings */
              unsigned long SLEEP_TIME = 0; //sleep forever
              #define CHILD_ID_R 0
              #define CHILD_ID_PC 1
              #define CHILD_ID_THR 3
              MyMessage msg(CHILD_ID_R, V_STATUS);    //room on/off child
              MyMessage pcMsg(CHILD_ID_PC, V_TEXT);   //people counter child
              MyMessage thrMsg(CHILD_ID_THR, V_TEXT); //Threshold child
              
              /* Motion Sensor setup*/
              #define DIGITAL_INPUT_SENSOR 2 // motion sensor digital pin (2 or 3 because just those pins are interrupt pins)
              MotionSensor motion(DIGITAL_INPUT_SENSOR);
              // int pirState = LOW; // we start, assuming no motion detected
              // int val = 0;        // variable for reading the pin status
              // int MotionInit = 2; // set init time in seconds. Should be set to 60s in production mode!
              
              /* IR Sensor setup*/
              #define ANALOG_IR_SENSORR 0 //IR Room Analog Pin
              #define ANALOG_IR_SENSORC 2 //IR Corridor Analog Pin
              #define IR_D_R 7            //IR Sensor Digital Pin for Room - EN Pin
              #define IR_D_C 8            //IR Sensor Digital Pin for Corridor - EN Pin
              #define LTIME 10000         // loop time (should not be lower than 8 seconds)
              #define MTIME 800           // measuring/person
              #define CALIBRATION_VAL 500 //read 500 values (250 from each sensor)
              //#define IR_BOOT 30 // Not needed for the new sensors caused by the enable pin
              
              /* OLED setup 
                For now only the OLED 128x32 monochrom displays are supported without modification
              */
              #ifdef USE_OLED
              // includes for OLED 128x32 and 128x64 support
              #include <SSD1306_text.h>
              SSD1306_text oled;
              
              #endif
              
              // some needed var declarations
              int irrVal = 0;      //analog value store for the room sensor
              int ircVal = 0;      //analog value store for the corridor sensor
              int threshold = 160; //if CALIBRATION is not defined, this threshold is used (okay for a 80cm doorway using reflection foil)
              int inout = -1;      //if inout== 0 -> out; if inout == 1 --> in; THIS STATE WILL BE SENT!
              int peopleCount = 0; //default state: nobody is inside the room
              
              // function prototypes
              // int checkMotion();
              void irSensor();
              int calibration();
              void send();
              
              void setup()
              {
                #ifdef USE_OLED
                // display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
                // display.display();
                oled.init();
                oled.clear();
                // oled.setTextSize(2);
                // oled.setCursor(0, 0);
                // oled.println("### Roode ###");
                // oled.setCursor(0,15);
                // oled.print("RooDe: ");
                // oled.print(ROODE_VERSION);
                // oled.println("MySensors: 2.2.0");
                #endif
              
                Serial.println("##### RooDe Presence Detection System #####");
              
                //Corridor Sensor Enable PIN
                pinMode(IR_D_C, OUTPUT);
              
                //Room Sensor Voltage Enable PIN
                pinMode(IR_D_R, OUTPUT);
              
                //Motion Sensor
                pinMode(DIGITAL_INPUT_SENSOR, INPUT); // declare motionsensor as input
              
              #ifdef CALIBRATION
                // Serial.println("#### initialize the motion sensor ####");
                //Sensor intialisation
                // for (int i = 0; i < MotionInit; i++) {
                //   wait(1000);
                // }
                motion.Setup(10);
                // Serial.println("#### motion sensor initialized ####");
              
                Serial.println("#### calibrate the ir sensors ####");
                threshold = calibration();
                Serial.print("New threshold is: ");
                Serial.println(threshold);
                send(thrMsg.set(threshold));
                Serial.println("#### calibration done ####");
              #endif
              
                Serial.println("#### Setting the PresenceCounter and Status to OUT (0) ####");
                send(msg.set(0));   //Setting presence status to 0
                send(pcMsg.set(0)); //Setting the people counter to 0
              }
              
              void presentation()
              {
                sendSketchInfo("RooDe", ROODE_VERSION);
                present(CHILD_ID_R, S_BINARY);
                present(CHILD_ID_PC, S_INFO);
              #ifdef USE_BATTERY
                present(CHILD_ID_BATTERY, S_CUSTOM);
              #endif
                present(CHILD_ID_THR, S_INFO);
              }
              
              void loop()
              {
              
                // Sleep until interrupt comes in on motion sensor. Send never an update
              
                if (motion.checkMotion() == LOW)
                {
                  irSensor();
                  digitalWrite(IR_D_R, LOW);
                  wait(1);
                  digitalWrite(IR_D_C, LOW);
                  sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), RISING, SLEEP_TIME);
                  irSensor();
                  while (motion.checkMotion() != LOW)
                  {
                    irSensor();
                  }
                }
              }
              
              // int checkMotion() {
              //   //Motion Sensor
              //   val = digitalRead(DIGITAL_INPUT_SENSOR);  // read input value
              //   if (val == HIGH) {            // check if the input is HIGH
              //
              //     if (pirState == LOW) {      // check if the pir status is LOW
              // #ifdef MY_DEBUG
              //       Serial.println("Motion detected");
              // #endif
              //       pirState = HIGH;          // set pir status to HIGH
              //     }
              //   } else {
              //     if (pirState == HIGH) {     //check if the pir status is HIGH
              // #ifdef MY_DEBUG
              //       Serial.println("No Motion");
              // #endif
              //       pirState = LOW;           // set the pir status to LOW
              //     }
              //   }
              //   return pirState;
              // }
              
              void irSensor()
              {
                int starttime = millis();
                int endtime = starttime;
              
                while ((endtime - starttime) <= LTIME) // do this loop for up to 5000mS
                {
                  // turn both sensors on
                  digitalWrite(IR_D_R, HIGH);
                  wait(1);
                  digitalWrite(IR_D_C, HIGH);
                  wait(5);
                  inout = -1;
              
                  irrVal = analogRead(ANALOG_IR_SENSORR);
                  wait(10);
                  ircVal = analogRead(ANALOG_IR_SENSORC);
              
              #ifdef MY_DEBUG
                  Serial.print("IRR:");
                  Serial.println(irrVal);
                  Serial.print("IRC:");
                  Serial.println(ircVal);
              #endif
                  if (irrVal > threshold && ircVal < threshold && inout != 1)
                  {
                    int startR = millis();
                    int endR = startR;
                    while ((endR - startR) <= MTIME)
                    {
                      irrVal = analogRead(ANALOG_IR_SENSORR);
                      wait(10);
                      ircVal = analogRead(ANALOG_IR_SENSORC);
                      if (ircVal > threshold && irrVal > threshold)
                      {
              #ifdef MY_DEBUG
                        Serial.print("In Loop IRR: ");
                        Serial.println(irrVal);
                        Serial.print("In Loop IRC: ");
                        Serial.println(ircVal);
                        Serial.print("Delay Time: ");
                        Serial.println(MTIME - (endR - startR));
              #endif
                        while (irrVal > threshold || ircVal > threshold)
                        {
                          irrVal = analogRead(ANALOG_IR_SENSORR);
                          wait(10);
                          ircVal = analogRead(ANALOG_IR_SENSORC);
                          if (ircVal > threshold && irrVal < threshold)
                          {
                            // turn both sensors off
                            digitalWrite(IR_D_R, LOW);
                            wait(1);
                            digitalWrite(IR_D_C, LOW);
                            inout = 0;
                            send();
                            break;
                          }
                          wait(11);
                        }
              
                        if (inout == 0)
                        {
                          wait(150);
                          ircVal = 0;
                          endR = millis();
                          starttime = millis();
                          endtime = starttime;
                          break;
                        }
                      }
                      else
                      {
                        wait(1);
                        endR = millis();
                      }
                    }
                  }
                  else
                  {
                    endtime = millis();
                  }
              
                  if (ircVal > threshold && irrVal < threshold && inout != 0)
                  {
                    int startC = millis();
                    int endC = startC;
                    while ((endC - startC) <= MTIME)
                    {
                      ircVal = analogRead(ANALOG_IR_SENSORC);
                      wait(10);
                      irrVal = analogRead(ANALOG_IR_SENSORR);
                      if (irrVal > threshold && ircVal > threshold)
                      {
              #ifdef MY_DEBUG
                        Serial.print("In Loop IRC: ");
                        Serial.println(ircVal);
                        Serial.print("In Loop IRR: ");
                        Serial.println(irrVal);
                        Serial.print("Delay Time: ");
                        Serial.println(MTIME - (endC - startC));
              #endif
                        while (irrVal > threshold || ircVal > threshold)
                        {
                          irrVal = analogRead(ANALOG_IR_SENSORR);
                          wait(10);
                          ircVal = analogRead(ANALOG_IR_SENSORC);
                          if (irrVal > threshold && ircVal < threshold)
                          {
                            // turn both sensors off
                            digitalWrite(IR_D_R, LOW);
                            wait(1);
                            digitalWrite(IR_D_C, LOW);
                            inout = 1;
                            send();
                            break;
                          }
                          wait(11);
                        }
              
                        if (inout == 1)
                        {
                          wait(150);
                          irrVal = 0;
                          endC = millis();
                          starttime = millis();
                          endtime = starttime;
                          break;
                        }
                      }
                      else
                      {
                        wait(11);
                        endC = millis();
                      }
                    }
                  }
                  else
                  {
                    endtime = millis();
                  }
                  wait(11);
                }
              }
              
              void send()
              {
                if (inout == 1)
                {
                  peopleCount++;
                  send(msg.set(inout));
                  wait(30);
                  send(pcMsg.set(peopleCount));
                }
                else if (inout == 0)
                {
                  if (peopleCount > 0)
                  {
                    peopleCount--;
                  }
                  if (peopleCount == 0)
                  {
                    send(msg.set(inout));
                  }
                  wait(30);
                  send(pcMsg.set(peopleCount));
                }
              
              #ifdef USE_BATTERY
                float voltage = battery.checkBatteryLevel();
                send(voltage_msg.set(voltage, 3)); // redVcc returns millivolts. Set wants volts and how many decimals (3 in our case)
                sendBatteryLevel(round((voltage - BATTERY_ZERO) * 100.0 / (BATTERY_FULL - BATTERY_ZERO)));
              #endif
              }
              
              int calibration()
              {
              
                digitalWrite(IR_D_C, HIGH);
                digitalWrite(IR_D_R, HIGH);
                delay(100);
                int distances[CALIBRATION_VAL];
                int max = 0;
                for (int m = 0; m < CALIBRATION_VAL; m = m + 2)
                {
                  delay(8);
                  irrVal = analogRead(ANALOG_IR_SENSORR);
                  delay(8);
                  ircVal = analogRead(ANALOG_IR_SENSORC);
              
                  //calculate the max without jumps for the room sensor
                  if ((irrVal >= max && (irrVal - max) < 30) || irrVal - max == irrVal)
                  {
                    Serial.println(irrVal);
                    max = irrVal;
                    distances[m] = irrVal;
                  }
                  else
                  {
                    distances[m] = 0;
                  }
              
                  //calculate the max without jumps for the corridor sensor
                  if (((ircVal >= max) && ((ircVal - max) < 30)) || ((ircVal - max) == ircVal))
                  {
                    Serial.println(ircVal);
                    max = ircVal;
                    distances[m + 1] = ircVal;
                  }
                  else
                  {
                    distances[m + 1] = 0;
                  }
                }
              
                // shutdown both sensors
                digitalWrite(IR_D_C, LOW);
                digitalWrite(IR_D_R, LOW);
                max = 0;
                //calculate the absolute max value to determine the new threshold
                for (int i = 0; i < CALIBRATION_VAL; i++)
                {
                  if (distances[i] >= max)
                  {
                    max = distances[i];
                  }
                }
                return max + 30; //add 30 to be super safe
              }
              
              /*
                - Not sure if this function ever will be used... But good idea to have this as backup
                - Tests will be show more about RAM problems
              */
              int freeRam()
              {
                extern int __heap_start, *__brkval;
                int v;
                return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
              }
              
              
              mfalkviddM Offline
              mfalkviddM Offline
              mfalkvidd
              Mod
              wrote on last edited by mfalkvidd
              #6

              @kai-bepperling I am not familiar with platformio, but it looks like ram should be fine.
              EDIT: you're allocating an array that is 1kB in size (500 integers). That brings the memory usage pretty close to maximum.

              One thing that seems strange to me is "overriding" send, and calling send from within send. To me, that should lead to endless recursion but you're not using send during calibration so I don't know what could be wrong.

              1 Reply Last reply
              0
              • Kai BepperlingK Offline
                Kai BepperlingK Offline
                Kai Bepperling
                wrote on last edited by Kai Bepperling
                #7

                If send had the same signature as the mysensors send it will be endless but it dont. Maybe i should rename my own send function.
                Should i clear the array by hand after the calibration? I thought this is not needed..

                Edit: thanks for the hint with the array. If i init the array with 250 ints the display is working for now.

                What is the best way to "clear/remove" an array?

                mfalkviddM 1 Reply Last reply
                1
                • Kai BepperlingK Kai Bepperling

                  If send had the same signature as the mysensors send it will be endless but it dont. Maybe i should rename my own send function.
                  Should i clear the array by hand after the calibration? I thought this is not needed..

                  Edit: thanks for the hint with the array. If i init the array with 250 ints the display is working for now.

                  What is the best way to "clear/remove" an array?

                  mfalkviddM Offline
                  mfalkviddM Offline
                  mfalkvidd
                  Mod
                  wrote on last edited by
                  #8

                  @kai-bepperling thanks for clarifying on the send function.

                  From what I can see, you don't need the array at all. Just check if the new value is larger than the max value directly.

                  1 Reply Last reply
                  2
                  • Kai BepperlingK Offline
                    Kai BepperlingK Offline
                    Kai Bepperling
                    wrote on last edited by
                    #9

                    Nothing more to say. Sometimes it can be that simple :sweat_smile:

                    1 Reply Last reply
                    1
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    16

                    Online

                    11.7k

                    Users

                    11.2k

                    Topics

                    113.1k

                    Posts


                    Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • MySensors
                    • OpenHardware.io
                    • Categories
                    • Recent
                    • Tags
                    • Popular