Combine a variety of coding in one Arduino code

profileSavionYHK
SHS.zip

SHS/doorbell/Buzzer.cpp

SHS/doorbell/Buzzer.cpp


#include   "Buzzer.h"
#include   < avr / wdt . h >

uint8_t buzzer_pin ;

#ifdef  ME_PORT_DEFINED
/**
 * Alternate Constructor which can call your own function to map the Buzzer to arduino port,
 * Buzzer pins are used and initialized here.
 * \param[in]
 *   None
 */
Buzzer :: Buzzer ()
{
  buzzer_pin  =   9 ;
}

/**
 * Alternate Constructor which can call your own function to map the Buzzer to arduino port,
 * If the hardware serial was selected, we will used the hardware serial.
 * \param[in]
 *   port - RJ25 port from PORT_1 to M2
 */
Buzzer :: Buzzer ( uint8_t port ) : MePort ( port )
{
  buzzer_pin  =  port ;
}

/**
 * Alternate Constructor which can call your own function to map the Buzzer to arduino port,
 * you can set any slot for the buzzer device.
 * \param[in]
 *   port - RJ25 port from PORT_1 to M2
 * \param[in]
 *   slot - SLOT1 or SLOT2
 */
Buzzer :: Buzzer ( uint8_t port ,  uint8_t slot ) : MePort ( port )
{
  buzzer_pin  =  s2 ;
   if ( slot  ==  SLOT2 )
   {
    buzzer_pin  =  s2 ;
   }
   else
   {
    buzzer_pin  =  s1 ;
   }
}
#else   // ME_PORT_DEFINED
/**
 * Alternate Constructor which can call your own function to map the Buzzer to arduino port,
 * \param[in]
 *   switchPin - arduino port for buzzer detect pin.
 */
Buzzer :: Buzzer ( int  pin )
{
  buzzer_pin  =  pin ;
}
#endif   // ME_PORT_DEFINED

/**
 * \par Function
 *    setpin
 * \par Description
 *    Reset the buzzer available pin by its arduino port.
 * \param[in]
 *    pin - arduino port for buzzer detect pin.
 * \par Output
 *    None
 * \par Return
 *    None
 * \par Others
 *    None
 */
void   Buzzer :: setpin ( int  pin )
{
  buzzer_pin  =  pin ;
}

/**
 * \par Function
 *    tone
 * \par Description
 *    Playing the tones.
 * \param[in]
 *    pin - Which pin on board that buzzer is connecting to.
 * \param[in]
 *    frequency - The speed of buzzer's tone play.
 * \param[in]
 *    duration - Time of a tone play.
 * \par Output
 *    None
 * \Return
 *    None.
 * \par Others
 *    Frequency (in hertz) and duration (in milliseconds).
 */
void   Buzzer :: tone ( int  pin ,  uint16_t frequency ,  uint32_t duration )
{
  buzzer_pin  =  pin ;
   int  period  =   1000000L   /  frequency ;
   int  pulse  =  period  /   2 ;
  pinMode ( buzzer_pin ,  OUTPUT );
   for   ( long  i  =   0 ;  i  <  duration  *   1000L ;  i  +=  period )
   {
    digitalWrite ( buzzer_pin ,  HIGH );
    delayMicroseconds ( pulse );
    digitalWrite ( buzzer_pin ,  LOW );
    delayMicroseconds ( pulse );
    wdt_reset ();
   }
}

/**
 * \par Function
 *    tone
 * \par Description
 *    Playing the tones.
 * \param[in]
 *    frequency - The speed of buzzer's tone play.
 * \param[in]
 *    duration - Time of a tone play.
 * \par Output
 *    None
 * \Return
 *    None.
 * \par Others
 *    Frequency (in hertz) and duration (in milliseconds).
 */
void   Buzzer :: tone ( uint16_t frequency ,  uint32_t duration )
{
     int  period  =   1000000L   /  frequency ;
     int  pulse  =  period  /   2 ;
    pinMode ( buzzer_pin ,  OUTPUT );
     for   ( long  i  =   0 ;  i  <  duration  *   1000L ;  i  +=  period )
     {
        digitalWrite ( buzzer_pin ,  HIGH );
        delayMicroseconds ( pulse );
        digitalWrite ( buzzer_pin ,  LOW );
        delayMicroseconds ( pulse );
        wdt_reset ();
     }
}

void   Buzzer :: _tone  ( float  noteFrequency ,   long  noteDuration ,   int  silentDuration )
{

     // tone(10,261,500);
     // delay(500);

       if ( silentDuration == 0 ){ silentDuration = 1 ;}

      tone ( buzzer_pin ,  noteFrequency ,  noteDuration );
      delay ( noteDuration );         //milliseconds to microseconds
       //noTone(PIN_Buzzer);
      delay ( silentDuration );
}


void   Buzzer :: bendTones ( float  initFrequency ,   float  finalFrequency ,   float  prop ,   long  noteDuration ,   int  silentDuration ){

   //Examples:
   //  bendTones (880, 2093, 1.02, 18, 1);
   //  bendTones (note_A5, note_C7, 1.02, 18, 0);

   if ( silentDuration == 0 ){ silentDuration = 1 ;}

   if ( initFrequency  <  finalFrequency )
   {
       for   ( int  i = initFrequency ;  i < finalFrequency ;  i = i * prop )   {
          _tone ( i ,  noteDuration ,  silentDuration );
       }

   }   else {

       for   ( int  i = initFrequency ;  i > finalFrequency ;  i = i / prop )   {
          _tone ( i ,  noteDuration ,  silentDuration );
       }
   }
}

/**
 * \par Function
 *    noTone
 * \par Description
 *    Do not playing the tones.
 * \param[in]
 *    pin - Which pin on board that buzzer is connecting to.
 * \par Output
 *    None
 * \Return
 *    None.
 * \par Others
 *    None
 */
void   Buzzer :: noTone ( int  pin )
{
  buzzer_pin  =  pin ;
  pinMode ( buzzer_pin ,  OUTPUT );
  digitalWrite ( buzzer_pin ,  LOW );
}

/**
 * \par Function
 *    noTone
 * \par Description
 *    Do not playing the tones.
 * \param[in]
 *    None
 * \par Output
 *    None
 * \Return
 *    None.
 * \par Others
 *    None
 */
void   Buzzer :: noTone ()
{
  pinMode ( buzzer_pin ,  OUTPUT );
  digitalWrite ( buzzer_pin ,  LOW );
}

SHS/doorbell/Buzzer.h

/** * \par Copyright (C), 2012-2016, MakeBlock * \class Buzzer * \brief Driver for Me Buzzer module. * @file Buzzer.h * @author MakeBlock * @version V1.0.0 * @date 2015/11/09 * @brief Header for Buzzer.cpp module * * \par Copyright * This software is Copyright (C), 2012-2016, MakeBlock. Use is subject to license \n * conditions. The main licensing options available are GPL V2 or Commercial: \n * * \par Open Source Licensing GPL V2 * This is the appropriate option if you want to share the source code of your \n * application with everyone you distribute it to, and you also want to give them \n * the right to share who uses it. If you wish to use this software under Open \n * Source Licensing, you must contribute all your source code to the open source \n * community in accordance with the GPL Version 2 when your application is \n * distributed. See http://www.gnu.org/copyleft/gpl.html * * \par Description * This file is a drive for Me Buzzer device, The Me Buzzer inherited the * MeSerial class from SoftwareSerial. * * \par Method List: * * 1. void Buzzer::setpin(int pin); * 2. void Buzzer::tone(int pin, uint16_t frequency, uint32_t duration); * 3. void Buzzer::tone(uint16_t frequency, uint32_t duration) * 4. void Buzzer::noTone(int pin); * 5. void Buzzer::noTone(); * * \par History: * <pre> * `<Author>` `<Time>` `<Version>` `<Descr>` * forfish 2015/11/09 1.0.0 Add description * </pre> * * @example BuzzerTest.ino */ #ifndef Buzzer_H #define Buzzer_H #include <stdint.h> #include <stdbool.h> #include <Arduino.h> #ifdef ME_PORT_DEFINED #include "MePort.h" #endif // ME_PORT_DEFINED /** * Class: Buzzer * \par Description * Declaration of Class Buzzer. */ #ifdef ME_PORT_DEFINED class Buzzer : public MePort #else class Buzzer #endif { public: #ifdef ME_PORT_DEFINED /** * Alternate Constructor which can call your own function to map the buzzer to arduino port, * no pins are used or initialized here. * \param[in] * None */ Buzzer(); /** * Alternate Constructor which can call your own function to map the Buzzer to arduino port, * If the hardware serial was selected, we will used the hardware serial. * \param[in] * port - RJ25 port from PORT_1 to M2 */ Buzzer(uint8_t port); /** * Alternate Constructor which can call your own function to map the Buzzer to arduino port, * you can set any slot for the buzzer device. * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 */ Buzzer(uint8_t port, uint8_t slot); #else // ME_PORT_DEFINED /** * Alternate Constructor which can call your own function to map the Buzzer to arduino port, * \param[in] * switchPin - arduino port for buzzer detect pin. */ Buzzer(int pin); #endif // ME_PORT_DEFINED /** * \par Function * setpin * \par Description * Reset the buzzer available pin by its arduino port. * \param[in] * pin - arduino port for buzzer detect pin. * \par Output * None * \par Return * None * \par Others * None */ void setpin(int pin); /** * \par Function * tone * \par Description * Playing the tones. * \param[in] * pin - Which pin on board that buzzer is connecting to. * \param[in] * frequency - The speed of buzzer's tone play. * \param[in] * duration - Time of a tone play. * \par Output * None * \Return * None. * \par Others * Frequency (in hertz) and duration (in milliseconds). */ void tone(int pin, uint16_t frequency, uint32_t duration); /** * \par Function * tone * \par Description * Playing the tones. * \param[in] * frequency - The speed of buzzer's tone play. * \param[in] * duration - Time of a tone play. * \par Output * None * \Return * None. * \par Others * Frequency (in hertz) and duration (in milliseconds). */ void tone(uint16_t frequency, uint32_t duration = 0); /** * \par Function * noTone * \par Description * Do not playing the tones. * \param[in] * pin - Which pin on board that buzzer is connecting to. * \par Output * None * \Return * None. * \par Others * None */ void _tone(float noteFrequency, long noteDuration, int silentDuration); void bendTones(float initFrequency, float finalFrequency, float prop, long noteDuration, int silentDuration); void noTone(int pin); /** * \par Function * noTone * \par Description * Do not playing the tones. * \param[in] * None * \par Output * None * \Return * None. * \par Others * None */ void noTone(); }; #endif

SHS/doorbell/doorbell.ino

#include "Buzzer.h" #include "Sounds.h" #include "PH20Port.h" PH20Port buzzerplay(P9); #include "Buzzer.h" int touch_PIN2 = 2; Buzzer mBuzzer = Buzzer(buzzerplay.pin1()); Buzzer buzzer(buzzerplay.pin1()); void setup() { pinMode(touch_PIN2,INPUT); } void loop() { if (digitalRead(touch_PIN2)==HIGH) { mBuzzer.bendTones(1500, 2500, 1.05, 20, 8); mBuzzer.bendTones(2499, 1500, 1.05, 25, 8); } else { buzzer.noTone(); } }

SHS/doorbell/PH20Port.cpp

#include "PH20Port.h" PH20Port_Sig PH20_Port[RJ25_MAX] = { { A3, NC, NC, NC, NC, NC }, //1 { A2, NC, NC, NC, NC, NC }, //2 { A1, NC, NC, NC, NC, NC }, //3 { A0, NC, NC, NC, NC, NC }, //4 { 7, A0, NC, NC, NC, NC }, //5 { 8, A1, NC, NC, NC, NC }, //6 { A5, A4, NC, NC, NC, NC }, //7 { 6, 5, NC, NC, NC, NC }, //8 { 3, NC, NC, NC, NC, NC }, //9 { 4, NC, NC, NC, NC, NC }, //10 { 5, NC, NC, NC, NC, NC }, //11 { 6, NC, NC, NC, NC, NC }, //12 { 4, 7, 8, A3, NC, NC }, //13 { 2, 7, A5, A4, NC, NC }, //14 { NC, NC, 3, 5, 6, NC }, //15 { NC, NC, A4, A5, 2, NC }, //16 }; /***********************Port*********************/ /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here */ PH20Port::PH20Port(void) { s1 = PH20_Port[0].s1; s2 = PH20_Port[0].s2; s3 = PH20_Port[0].s3; s4 = PH20_Port[0].s4; s5 = PH20_Port[0].s5; s6 = PH20_Port[0].s6; _port = 0; } /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here, but PWM frequency set to 976 Hz * \param[in] * port - RJ25 port from PORT_1 to M2 */ PH20Port::PH20Port(uint8_t port) { if (port < 1) return; s1 = PH20_Port[port-1].s1; s2 = PH20_Port[port-1].s2; s3 = PH20_Port[port-1].s3; s4 = PH20_Port[port-1].s4; s5 = PH20_Port[port-1].s5; s6 = PH20_Port[port-1].s6; _port = port; } /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here, but PWM frequency set to 976 Hz * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 */ PH20Port::PH20Port(uint8_t port, uint8_t slot) { if (port < 1) return; s1 = PH20_Port[port-1].s1; s2 = PH20_Port[port-1].s2; _port = port; _slot = slot; } /** * \par Function * getPort * \par Description * Get current valid port of current RJ25 object * \par Output * None * \return * Port bumber from PORT_1 to M2 * \par Others * None */ uint8_t PH20Port::getPort() { return(_port); } /** * \par Function * getSlot * \par Description * Get current valid slot of current RJ25 object's port * \par Output * None * \return * Slot bumber SLOT1 or SLOT2 * \par Others * None */ uint8_t PH20Port::getSlot(void) { return(_slot); } /** * \par Function * dRead1 * \par Description * Read the digital input value on slot1 of current RJ25 object's port * \param[in] * mode - digital input mode INPUT or INPUT_PULLUP * \par Output * None * \return * Digital input value * \par Others * None */ bool PH20Port::dRead1(uint8_t mode) { bool val; pinMode(s1, mode); val = digitalRead(s1); return(val); } /** * \par Function * dRead2 * \par Description * Read the digital input value on slot2 of current RJ25 object's port * \param[in] * mode - digital input mode INPUT or INPUT_PULLUP * \par Output * None * \return * Digital input value * \par Others * None */ bool PH20Port::dRead2(uint8_t mode) { bool val; pinMode(s2, mode); val = digitalRead(s2); return(val); } bool PH20Port::dRead3(uint8_t mode) { bool val; pinMode(s3, mode); val = digitalRead(s3); return(val); } bool PH20Port::dRead4(uint8_t mode) { bool val; pinMode(s4, mode); val = digitalRead(s4); return(val); } bool PH20Port::dRead5(uint8_t mode) { bool val; pinMode(s5, mode); val = digitalRead(s5); return(val); } /** * \par Function * dpRead1 * \par Description * Read the digital input value on slot1 of current RJ25 object's port, the input * mode set as INPUT_PULLUP. * \par Output * None * \return * Digital input value * \par Others * None */ bool PH20Port::dpRead1(void) { bool val; pinMode(s1, INPUT_PULLUP); val = digitalRead(s1); return(val); } /** * \par Function * dpRead2 * \par Description * Read the digital input value on slot2 of current RJ25 object's port, the input * mode set as INPUT_PULLUP. * \par Output * None * \return * Digital input value * \par Others * None */ bool PH20Port::dpRead2(void) { bool val; pinMode(s2, INPUT_PULLUP); val = digitalRead(s2); return(val); } /** * \par Function * dWrite1 * \par Description * Set the digital output value on slot1 of current RJ25 object's port * \param[in] * value - digital output value HIGH or LOW * \par Output * None * \return * None * \par Others * None */ void PH20Port::dWrite1(bool value) { pinMode(s1, OUTPUT); digitalWrite(s1, value); } /** * \par Function * dWrite2 * \par Description * Set the digital output value on slot2 of current RJ25 object's port * \param[in] * value - digital output value HIGH or LOW * \par Output * None * \return * None * \par Others * None */ void PH20Port::dWrite2(bool value) { pinMode(s2, OUTPUT); digitalWrite(s2, value); } void PH20Port::dWrite3(bool value) { pinMode(s3, OUTPUT); digitalWrite(s3, value); } void PH20Port::dWrite4(bool value) { pinMode(s4, OUTPUT); digitalWrite(s4, value); } void PH20Port::dWrite5(bool value) { pinMode(s5, OUTPUT); digitalWrite(s5, value); } /** * \par Function * aRead1 * \par Description * Read the analog value on slot1 of current RJ25 object's port * \par Output * None * \return * Analog value from 0-1023 * \par Others * None */ int16_t PH20Port::aRead1(void) { int16_t val; pinMode(s1, INPUT); val = analogRead(s1); return(val); } /** * \par Function * aRead2 * \par Description * Read the analog value on slot2 of current RJ25 object's port * \par Output * None * \return * Analog value from 0-1023 * \par Others * None */ int16_t PH20Port::aRead2(void) { int16_t val; pinMode(s2, INPUT); val = analogRead(s2); return(val); } int16_t PH20Port::aRead3(void) { int16_t val; pinMode(s3, INPUT); val = analogRead(s3); return(val); } int16_t PH20Port::aRead4(void) { int16_t val; pinMode(s4, INPUT); val = analogRead(s4); return(val); } int16_t PH20Port::aRead5(void) { int16_t val; pinMode(s5, INPUT); val = analogRead(s5); return(val); } /** * \par Function * aWrite1 * \par Description * Set the PWM output value on slot1 of current RJ25 object's port * \param[in] * value - Analog value between 0 to 255 * \par Output * None * \return * None * \par Others * None */ void PH20Port::aWrite1(int16_t value) { analogWrite(s1, value); } /** * \par Function * aWrite2 * \par Description * Set the PWM output value on slot2 of current RJ25 object's port * \param[in] * value - Analog value between 0 to 255 * \par Output * None * \return * None * \par Others * None */ void PH20Port::aWrite2(int16_t value) { analogWrite(s2, value); } void PH20Port::aWrite3(int16_t value) { analogWrite(s3, value); } void PH20Port::aWrite4(int16_t value) { analogWrite(s4, value); } void PH20Port::aWrite5(int16_t value) { analogWrite(s5, value); } /** * \par Function * reset * \par Description * Reset the RJ25 available PIN by its port * \param[in] * port - RJ25 port from PORT_1 to M2 * \par Output * None * \return * None * \par Others * None */ void PH20Port::reset(uint8_t port) { if ( port < 1) return; s1 = PH20_Port[port-1].s1; s2 = PH20_Port[port-1].s2; _port = port; } /** * \par Function * reset * \par Description * Reset the RJ25 available PIN by its port and slot * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 * \par Output * None * \return * None * \par Others * None */ void PH20Port::reset(uint8_t port, uint8_t slot) { if ( port < 1) return; s1 = PH20_Port[port-1].s1; s2 = PH20_Port[port-1].s2; _port = port; _slot = slot; } /** * \par Function * pin1 * \par Description * Return the arduino pin number of current RJ25 object's slot1 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t PH20Port::pin1(void) { return(s1); } /** * \par Function * pin2 * \par Description * Return the arduino pin number of current RJ25 object's slot2 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t PH20Port::pin2(void) { return(s2); } uint8_t PH20Port::pin3(void) { return(s3); } uint8_t PH20Port::pin4(void) { return(s4); } uint8_t PH20Port::pin5(void) { return(s5); } /** * \par Function * pin * \par Description * Return the arduino pin number of current RJ25 object's port, if the RJ25 module * have one available PIN. * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t PH20Port::pin(void) { return(_slot == SLOT_1 ? s1 : s2); } /** * \par Function * pin * \par Description * Return the arduino pin number of current RJ25 object's port * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t PH20Port::pin(uint8_t port, uint8_t slot) { if ( port < 1) return; return(slot == SLOT_1 ? PH20_Port[port-1].s1 : PH20_Port[port-1].s2); }

SHS/doorbell/PH20Port.h

#ifndef _PH20Port_H_ #define _PH20Port_H_ #include <Arduino.h> #include <avr/interrupt.h> #include <avr/io.h> #include <util/delay.h> #include <stdint.h> #include <stdlib.h> #define RJ25_MAX 16 #define P1 1 #define P2 2 #define P3 3 #define P4 4 #define P5 5 #define P6 6 #define P7 7 #define P8 8 #define P9 9 #define P10 10 #define P11 11 #define P12 12 #define P13 13 #define P14 14 #define P15 15 #define P16 16 /** * A structure to represent PH20Port Signal. */ typedef struct { uint8_t s1; uint8_t s2; uint8_t s3; uint8_t s4; uint8_t s5; uint8_t s6; } PH20Port_Sig; extern PH20Port_Sig PH20_Port[RJ25_MAX]; // PH20Port[0] is nonsense #define NC (0) //use UART RX for NULL port #define SLOT1 (1) #define SLOT2 (2) #define SLOT3 (3) #define SLOT4 (4) #define SLOT5 (5) #define SLOT6 (6) #define SLOT_1 SLOT1 #define SLOT_2 SLOT2 #define SLOT_3 SLOT3 #define SLOT_4 SLOT4 #define SLOT_5 SLOT3 #define SLOT_6 SLOT4 #ifndef FALSE #define FALSE (0) #endif #ifndef TRUE #define TRUE (1) #endif /** * Class: PH20Port * * \par Description * Declaration of Class PH20Port */ class PH20Port { public: /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here */ PH20Port(void); /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here, but PWM frequency set to 976 Hz * \param[in] * port - RJ25 port from PORT_1 to M2 */ PH20Port(uint8_t port); /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here, but PWM frequency set to 976 Hz * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 */ PH20Port(uint8_t port, uint8_t slot); /** * \par Function * getPort * \par Description * Get current valid port of current RJ25 object * \par Output * None * \return * Port bumber from PORT_1 to M2 * \par Others * None */ uint8_t getPort(void); /** * \par Function * getSlot * \par Description * Get current valid slot of current RJ25 object's port * \par Output * None * \return * Slot bumber SLOT1 or SLOT2 * \par Others * None */ uint8_t getSlot(void); /** * \par Function * dRead1 * \par Description * Read the digital input value on slot1 of current RJ25 object's port * \param[in] * mode - digital input mode INPUT or INPUT_PULLUP * \par Output * None * \return * Digital input value * \par Others * None */ bool dRead1(uint8_t mode = INPUT); /** * \par Function * dRead2 * \par Description * Read the digital input value on slot2 of current RJ25 object's port * \param[in] * mode - digital input mode INPUT or INPUT_PULLUP * \par Output * None * \return * Digital input value * \par Others * None */ bool dRead2(uint8_t mode = INPUT); bool dRead3(uint8_t mode = INPUT); bool dRead4(uint8_t mode = INPUT); bool dRead5(uint8_t mode = INPUT); /** * \par Function * dpRead1 * \par Description * Read the digital input value on slot1 of current RJ25 object's port, the input * mode set as INPUT_PULLUP. * \par Output * None * \return * Digital input value * \par Others * None */ bool dpRead1(void); /** * \par Function * dpRead2 * \par Description * Read the digital input value on slot2 of current RJ25 object's port, the input * mode set as INPUT_PULLUP. * \par Output * None * \return * Digital input value * \par Others * None */ bool dpRead2(void); /** * \par Function * dWrite1 * \par Description * Set the digital output value on slot1 of current RJ25 object's port * \param[in] * value - digital output value HIGH or LOW * \par Output * None * \return * None * \par Others * None */ void dWrite1(bool value); /** * \par Function * dWrite2 * \par Description * Set the digital output value on slot2 of current RJ25 object's port * \param[in] * value - digital output value HIGH or LOW * \par Output * None * \return * None * \par Others * None */ void dWrite2(bool value); void dWrite3(bool value); void dWrite4(bool value); void dWrite5(bool value); /** * \par Function * aRead1 * \par Description * Read the analog value on slot1 of current RJ25 object's port * \par Output * None * \return * Analog value from 0-1023 * \par Others * None */ int16_t aRead1(void); /** * \par Function * aRead2 * \par Description * Read the analog value on slot2 of current RJ25 object's port * \par Output * None * \return * Analog value from 0-1023 * \par Others * None */ int16_t aRead2(void); int16_t aRead3(void); int16_t aRead4(void); int16_t aRead5(void); /** * \par Function * aWrite1 * \par Description * Set the PWM output value on slot1 of current RJ25 object's port * \param[in] * value - Analog value between 0 to 255 * \par Output * None * \return * None * \par Others * None */ void aWrite1(int16_t value); /** * \par Function * aWrite2 * \par Description * Set the PWM output value on slot2 of current RJ25 object's port * \param[in] * value - Analog value between 0 to 255 * \par Output * None * \return * None * \par Others * None */ void aWrite2(int16_t value); void aWrite3(int16_t value); void aWrite4(int16_t value); void aWrite5(int16_t value); /** * \par Function * reset * \par Description * Reset the RJ25 available PIN by its port * \param[in] * port - RJ25 port from PORT_1 to M2 * \par Output * None * \return * None * \par Others * None */ void reset(uint8_t port); /** * \par Function * reset * \par Description * Reset the RJ25 available PIN by its port and slot * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 * \par Output * None * \return * None * \par Others * None */ void reset(uint8_t port, uint8_t slot); /** * \par Function * pin1 * \par Description * Return the arduino pin number of current RJ25 object's slot1 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t pin1(void); /** * \par Function * pin2 * \par Description * Return the arduino pin number of current RJ25 object's slot2 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t pin2(void); uint8_t pin3(void); uint8_t pin4(void); uint8_t pin5(void); /** * \par Function * pin * \par Description * Return the arduino pin number of current RJ25 object's port, if the RJ25 module * have one available PIN. * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t pin(void); /** * \par Function * pin * \par Description * Return the arduino pin number of current RJ25 object's port * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t pin(uint8_t port, uint8_t slot); protected: /** * \par Description * Variables used to store the slot1 gpio number */ uint8_t s1, s2, s3, s4, s5, s6; /** * \par Description * Variables used to store the port */ uint8_t _port; /** * \par Description * Variables used to store the slot */ uint8_t _slot; }; #endif // _RH20Port_H_

SHS/doorbell/Sounds.h

#ifndef _SOUNDS_H_ #define _SOUNDS_H_ typedef enum { E_NOTE, E_SOUND, E_MUSIC, E_BUZZER_TYPE_MAX, }E_BUZZER_TYPE; typedef enum { E_BEAT_8_1, E_BEAT_4_1, E_BEAT_2_1, E_BEAT_1, E_BEAT_2, E_BEAT_4 }E_MUSIC_BEAT; typedef struct { uint16_t note; E_MUSIC_BEAT beat; }ST_MUSIC_TYPE; //*********************************************************************************** //*********************************SOUNDS DEFINES************************************ //*********************************************************************************** // Reference: This list was adapted from the table located here: // http://www.phy.mtu.edu/~suits/notefreqs.html #define note_C0 16.35 //C0 #define note_Db0 17.32 //C#0/Db0 #define note_D0 18.35 //D0 #define note_Eb0 19.45 //D#0/Eb0 #define note_E0 20.6 //E0 #define note_F0 21.83 //F0 #define note_Gb0 23.12 //F#0/Gb0 #define note_G0 24.5 //G0 #define note_Ab0 25.96 //G#0/Ab0 #define note_A0 27.5 //A0 #define note_Bb0 29.14 //A#0/Bb0 #define note_B0 30.87 //B0 #define note_C1 32.7 //C1 #define note_Db1 34.65 //C#1/Db1 #define note_D1 36.71 //D1 #define note_Eb1 38.89 //D#1/Eb1 #define note_E1 41.2 //E1 #define note_F1 43.65 //F1 #define note_Gb1 46.25 //F#1/Gb1 #define note_G1 49 //G1 #define note_Ab1 51.91 //G#1/Ab1 #define note_A1 55 //A1 #define note_Bb1 58.27 //A#1/Bb1 #define note_B1 61.74 //B1 #define note_C2 65.41 //C2 (Middle C) #define note_Db2 69.3 //C#2/Db2 #define note_D2 73.42 //D2 #define note_Eb2 77.78 //D#2/Eb2 #define note_E2 82.41 //E2 #define note_F2 87.31 //F2 #define note_Gb2 92.5 //F#2/Gb2 #define note_G2 98 //G2 #define note_Ab2 103.83 //G#2/Ab2 #define note_A2 110 //A2 #define note_Bb2 116.54 //A#2/Bb2 #define note_B2 123.47 //B2 #define note_C3 130.81 //C3 #define note_Db3 138.59 //C#3/Db3 #define note_D3 146.83 //D3 #define note_Eb3 155.56 //D#3/Eb3 #define note_E3 164.81 //E3 #define note_F3 174.61 //F3 #define note_Gb3 185 //F#3/Gb3 #define note_G3 196 //G3 #define note_Ab3 207.65 //G#3/Ab3 #define note_A3 220 //A3 #define note_Bb3 233.08 //A#3/Bb3 #define note_B3 246.94 //B3 #define note_C4 261.63 //C4 #define note_Db4 277.18 //C#4/Db4 #define note_D4 293.66 //D4 #define note_Eb4 311.13 //D#4/Eb4 #define note_E4 329.63 //E4 #define note_F4 349.23 //F4 #define note_Gb4 369.99 //F#4/Gb4 #define note_G4 392 //G4 #define note_Ab4 415.3 //G#4/Ab4 #define note_A4 440 //A4 #define note_Bb4 466.16 //A#4/Bb4 #define note_B4 493.88 //B4 #define note_C5 523.25 //C5 #define note_Db5 554.37 //C#5/Db5 #define note_D5 587.33 //D5 #define note_Eb5 622.25 //D#5/Eb5 #define note_E5 659.26 //E5 #define note_F5 698.46 //F5 #define note_Gb5 739.99 //F#5/Gb5 #define note_G5 783.99 //G5 #define note_Ab5 830.61 //G#5/Ab5 #define note_A5 880 //A5 #define note_Bb5 932.33 //A#5/Bb5 #define note_B5 987.77 //B5 #define note_C6 1046.5 //C6 #define note_Db6 1108.73 //C#6/Db6 #define note_D6 1174.66 //D6 #define note_Eb6 1244.51 //D#6/Eb6 #define note_E6 1318.51 //E6 #define note_F6 1396.91 //F6 #define note_Gb6 1479.98 //F#6/Gb6 #define note_G6 1567.98 //G6 #define note_Ab6 1661.22 //G#6/Ab6 #define note_A6 1760 //A6 #define note_Bb6 1864.66 //A#6/Bb6 #define note_B6 1975.53 //B6 #define note_C7 2093 //C7 #define note_Db7 2217.46 //C#7/Db7 #define note_D7 2349.32 //D7 #define note_Eb7 2489.02 //D#7/Eb7 #define note_E7 2637.02 //E7 #define note_F7 2793.83 //F7 #define note_Gb7 2959.96 //F#7/Gb7 #define note_G7 3135.96 //G7 #define note_Ab7 3322.44 //G#7/Ab7 #define note_A7 3520 //A7 #define note_Bb7 3729.31 //A#7/Bb7 #define note_B7 3951.07 //B7 #define note_C8 4186.01 //C8 #define note_Db8 4434.92 //C#8/Db8 #define note_D8 4698.64 //D8 #define note_Eb8 4978.03 //D#8/Eb8 #define S_connection 0 #define S_disconnection 1 #define S_buttonPushed 2 #define S_mode1 3 #define S_mode2 4 #define S_mode3 5 #define S_surprise 6 #define S_OhOoh 7 #define S_OhOoh2 8 #define S_cuddly 9 #define S_sleeping 10 #define S_happy 11 #define S_superHappy 12 #define S_happy_short 13 #define S_sad 14 #define S_confused 15 #define S_fart1 16 #define S_fart2 17 #define S_fart3 18 #define S_didi 19 #endif /* _SOUNDS_H_ */

SHS/Intelligent_access_control/EM_TTP229.cpp

#include "EM_TTP229.h" ST_KEY_MAP em_ttp_keymap[16] = { {"1", 0xFFFE}, {"2", 0xFFFD}, {"3", 0xFFFB}, {"4", 0xFFEF}, {"5", 0xFFDF}, {"6", 0xFFBF}, {"7", 0xFEFF}, {"8", 0xFDFF}, {"9", 0xFBFF}, {"*", 0xEFFF}, {"0", 0xDFFF}, {"#", 0xBFFF}, {"D", 0x7FFF}, {"C", 0xF7FF}, {"B", 0xFF7F}, {"A", 0xFFF7}, }; void EM_TTP229::initTTP229(uint8_t SclPin, uint8_t SdoPin) { SCLPin = SclPin; SDOPin = SdoPin; pinMode(SCLPin , OUTPUT); pinMode(SDOPin , INPUT); } uint16_t EM_TTP229::GetKeyCode(void) { unsigned int DATA = 0; pinMode(SDOPin , OUTPUT); digitalWrite(SDOPin, HIGH); delayMicroseconds(93); digitalWrite(SDOPin, LOW); delayMicroseconds(10); pinMode(SDOPin , INPUT); for (int i = 0; i < 16; i++) { digitalWrite(SCLPin, HIGH); digitalWrite(SCLPin, LOW); DATA |= digitalRead(SDOPin) << i; } delay(4); return DATA & 0xFFFF; } String EM_TTP229::GetKeyMap(void) { byte i; uint16_t keycode = GetKeyCode(); ST_KEY_MAP *irkeymap = em_ttp_keymap; for (i = 0; i < KEY_MAX; i++) { // Serial.println(irkeymap[i].keycode); if (irkeymap[i].keycode == keycode) return irkeymap[i].keyname; } return ""; } uint16_t EM_TTP229::GetKey(void) { byte i; uint16_t keycode = GetKeyCode(); ST_KEY_MAP *irkeymap = em_ttp_keymap; for (i = 0; i < KEY_MAX; i++) { // Serial.println(irkeymap[i].keycode); if (irkeymap[i].keycode == keycode) return i; } return 0xff; }

SHS/Intelligent_access_control/EM_TTP229.h

#ifndef _TTP229_H_ #define _TTP229_H_ #include <Arduino.h> #define KEY_MAX 16 typedef struct { String keyname; uint16_t keycode; } ST_KEY_MAP; typedef enum { EM_KEYCODE_1 = 0, EM_KEYCODE_2, EM_KEYCODE_3, EM_KEYCODE_4, EM_KEYCODE_5, EM_KEYCODE_6, EM_KEYCODE_7, EM_KEYCODE_8, EM_KEYCODE_9, EM_KEYCODE_0, EM_KEYCODE_A, EM_KEYCODE_B, EM_KEYCODE_C, EM_KEYCODE_D, IR_KEYCODE_STAR, IR_KEYCODE_POUND, } E_EM_KEYCODE; extern ST_KEY_MAP em_ttp_keymap[]; class EM_TTP229 { private: uint8_t SCLPin, SDOPin; public: void initTTP229(uint8_t SclPin, uint8_t SdoPin); uint16_t GetKeyCode(void); String GetKeyMap(void); uint16_t GetKey(void); }; #endif /* _KEYMAY_H_ */

SHS/Intelligent_access_control/Intelligent_access_control.ino

#include "EM_TTP229.h" EM_TTP229 mTTP229; int SCLPin = 9, SDOPin = 8; String Read_Key () { String key_name = mTTP229.GetKeyMap(); char * result = (char *)key_name.c_str(); return result; } #include <Servo.h> String item; volatile int number; String password[]={"0", "0", "0"}; Servo servo_12; void setup(){ item = ""; number = 0; mTTP229.initTTP229(SCLPin, SDOPin); Serial.begin(9600); servo_12.attach(12); } void loop(){ item = Read_Key(); if (item == "1" && number == 0) { Serial.println(item); password[(int)(0)] = item; number = 1; delay(100); } if (item == "2" && number == 1) { Serial.println(item); password[(int)(1)] = item; number = 2; delay(100); } if (item == "3" && number == 2) { Serial.println(item); password[(int)(2)] = item; number = 3; delay(100); } if (password[(int)(0)] == "1" && (password[(int)(1)] == "2" && password[(int)(2)] == "3")) { Serial.println("hello"); servo_12.write(0); delay(2000); password[(int)(0)] = "0"; password[(int)(1)] = "0"; password[(int)(2)] = "0"; number = 0; } else { servo_12.write(90); delay(20); } }

SHS/remote_control/IR_remote.cpp

SHS/remote_control/IR_remote.cpp


#include   "IR_remote.h"
#include   "Keymap.h"
// Provides ISR
#ifndef  __AVR_ATmega32U4__
#include   < avr / interrupt . h >

volatile  irparams_t irparams ;
bool  MATCH ( uint8_t measured_ticks ,  uint8_t desired_us )
{
   // Serial.print(measured_ticks);Serial.print(",");Serial.println(desired_us);
   return ( measured_ticks  >=  desired_us  -   ( desired_us >> 2 ) - 1   &&  measured_ticks  <=  desired_us  +   ( desired_us >> 2 ) + 1 );
}

ISR ( TIMER_INTR_NAME )
{
   // Serial.println("ISR");
    //Serial.println(millis());
  uint8_t irdata  =   ( uint8_t ) digitalRead ( irparams . recvpin );
   // uint32_t new_time = micros();
   // uint8_t timer = (new_time - irparams.lastTime)>>6;
  irparams . timer ++ ;   // One more 50us tick
   if   ( irparams . rawlen  >=  RAWBUF )
   {
     // Buffer overflow
    irparams . rcvstate  =  STATE_STOP ;
   }
   switch ( irparams . rcvstate )
   {
     case  STATE_IDLE :   // In the middle of a gap
       if   ( irdata  ==  MARK )
       {
        irparams . rawlen  =   0 ;
        irparams . timer  =   0 ;
        irparams . rcvstate  =  STATE_MARK ;
       }
       break ;
     case  STATE_MARK :   // timing MARK
       if   ( irdata  ==  SPACE )
       {
         // MARK ended, record time
        irparams . rawbuf [ irparams . rawlen ++ ]   =  irparams . timer ;
        irparams . timer  =   0 ;
        irparams . rcvstate  =  STATE_SPACE ;
       }
       break ;
     case  STATE_SPACE :   // timing SPACE
       if   ( irdata  ==  MARK )
       {
         // SPACE just ended, record it
        irparams . rawbuf [ irparams . rawlen ++ ]   =  irparams . timer ;
        irparams . timer  =   0 ;
        irparams . rcvstate  =  STATE_MARK ;
       }
       else
       {   // SPACE
         if   ( irparams . timer  >  GAP_TICKS )
         {
           // big SPACE, indicates gap between codes
           // Mark current code as ready for processing
           // Switch to STOP
           // Don't reset timer; keep counting space width
          irparams . rcvstate  =  STATE_STOP ;
          irparams . lastTime  =  millis ();
         }  
       }
       break ;
     case  STATE_STOP :   // waiting, measuring gap
       if ( millis ()   -  irparams . lastTime  >   120 )
       {
        irparams . rawlen  =   0 ;
        irparams . timer  =   0 ;
        irparams . rcvstate  =  STATE_IDLE ;
       }
       else   if   ( irdata  ==  MARK )
       {  
         // reset gap timer
        irparams . timer  =   0 ;
       }
       break ;
   }
   // irparams.lastTime = new_time;
}

/**
 * Alternate Constructor which can call your own function to map the IR to arduino port,
 * no pins are used or initialized here.
 * \param[in]
 *   None
 */
IRremote :: IRremote ( int  pin )
{
  pinMode ( pin , INPUT );
  irparams . recvpin  =  pin ;
   // attachInterrupt(INT0, irISR, CHANGE);
  
  irDelayTime  =   0 ;
  irIndex  =   0 ;
  irRead  =   0 ;
  irReady  =   false ;
  irBuffer  =   "" ;
  irPressed  =   false ;
  begin ();
}

/**
 * \par Function
 *    begin
 * \par Description
 *    Initialize interrupt.
 * \param[in]
 *    None
 * \par Output
 *    None
 * \par Return
 *    None
 * \par Others
 *    None
 */
void   IRremote :: begin ()
{
  cli ();
   // setup pulse clock timer interrupt
   //Prescale /8 (16M/8 = 0.5 microseconds per tick)
   // Therefore, the timer interval can range from 0.5 to 128 microseconds
   // depending on the reset value (255 to 0)
  TIMER_CONFIG_NORMAL ();

   //Timer2 Overflow Interrupt Enable
  TIMER_ENABLE_INTR ;

   // TIMER_RESET;

  sei ();    // enable interrupts

   // initialize state machine variables
  irparams . rawlen  =   0 ;
  irparams . rcvstate  =  STATE_IDLE ;
}

/**
 * \par Function
 *    end
 * \par Description
 *    Close the interrupt.
 * \param[in]
 *    None
 * \par Output
 *    None
 * \par Return
 *    None
 * \par Others
 *    None
 */
void   IRremote :: end ()
{
  EIMSK  &=   ~ ( 1   <<  INT0 );
}

/**
 * \par Function
 *    decode
 * \par Description
 *    Decodes the received IR message.
 * \param[in]
 *    None
 * \par Output
 *    None
 * \par Return
 *    Returns 0 if no data ready, 1 if data ready.
 * \par Others
 *    Results of decoding are stored in results.
 */
ErrorStatus   IRremote :: decode ()
{
  rawbuf  =  irparams . rawbuf ;
  rawlen  =  irparams . rawlen ;
   if   ( irparams . rcvstate  !=  STATE_STOP )
   {
      return  ERROR ;
   }

   if   ( decodeNEC ())
   {
    begin ();
     return  SUCCESS ;
   }
  begin ();
   return  ERROR ;
}

/**
 * \par Function
 *    decodeNEC
 * \par Description
 *    Decodes NEC the received IR message.
 * \param[in]
 *    None
 * \par Output
 *    None
 * \par Return
 *    Returns ERROR if decode NEC no done, SUCCESS if decode NEC done.
 * \par Others
 *    Results of decode NEC.
 */
// NECs have a repeat only 4 items long
ErrorStatus   IRremote :: decodeNEC ()
{
   static   unsigned   long  repeat_value  =   0xFFFFFFFF ;
   static  byte repeta_time  =   0 ;
  uint32_t data  =   0 ;
   int  offset  =   0 ;   // Skip first space
   // Initial mark
   if   ( ! MATCH ( rawbuf [ offset ],  NEC_HDR_MARK / 50 ))  
   {
     return  ERROR ;
   }
  offset ++ ;
   // Check for repeat
   if   ( rawlen  ==   3   &&
    MATCH ( rawbuf [ offset ],  NEC_RPT_SPACE / 50 )   &&
    MATCH ( rawbuf [ offset + 1 ],  NEC_BIT_MARK / 50 ))  
   {   
     rawbuf [ offset ]   =   0 ;
     rawbuf [ offset + 1 ]   =   0 ;
     repeta_time ++ ;
     // if(repeta_time > 1) {
        repeta_time  =   0 ;
        bits  =   0 ;
         value   =  repeat_value ;
        // Serial.println("REPEAT");
        decode_type  =  NEC ;
         return  SUCCESS ;
    //  }
   }
   if   ( rawlen  <   ( 2   *  NEC_BITS  +   3 ))  
   {
     return  ERROR ;
   }
   // Initial space  
   if   ( ! MATCH ( rawbuf [ offset ],  NEC_HDR_SPACE / 50 ))  
   {
     return  ERROR ;
   }
  rawbuf [ offset ]   =   0 ;
  offset ++ ;
   for   ( int  i  =   0 ;  i  <  NEC_BITS ;  i ++ )
   {
     if   ( ! MATCH ( rawbuf [ offset ],  NEC_BIT_MARK / 50 ))  
     {
       return  ERROR ;
     }
    rawbuf [ offset ]   =   0 ;
    offset ++ ;
     if   ( MATCH ( rawbuf [ offset ],  NEC_ONE_SPACE / 50 ))
     {
       //data = (data << 1) | 1;
      data  =   ( data  >>   1 )   |   0x80000000 ;
     }  
     else   if   ( MATCH ( rawbuf [ offset ],  NEC_ZERO_SPACE / 50 ))
     {
       //data <<= 1;
      data  >>=   1 ;
     }  
     else  
     {
       return  ERROR ;
     }
    offset ++ ;
   }
   // Success
  bits  =  NEC_BITS ;
   value   =  data ;
  repeat_value  =  data ;
  decode_type  =  NEC ;
  repeta_time  =   0 ;
   return  SUCCESS ;
}

/**
 * \par Function
 *    mark
 * \par Description
 *    Sends an IR mark for the specified number of microseconds.
 * \param[in]
 *    us - THe time of a PWM.
 * \par Output
 *    None
 * \par Return
 *    None
 * \par Others
 *    None
 */
void   IRremote :: mark ( uint16_t us )
{
   // Sends an IR mark for the specified number of microseconds.
   // The mark output is modulated at the PWM frequency.
  TIMER_ENABLE_PWM ;   // Enable pin 3 PWM output
  delayMicroseconds ( us );
}

/**
 * \par Function
 *    space
 * \par Description
 *    Sends an IR mark for the specified number of microseconds.
 * \param[in]
 *    us - THe time of a PWM.
 * \par Output
 *    None
 * \par Return
 *    None
 * \par Others
 *    None
 */
/* Leave pin off for time (given in microseconds) */
void   IRremote :: space ( uint16_t us )
{
   // Sends an IR space for the specified number of microseconds.
   // A space is no output, so the PWM output is disabled.
  TIMER_DISABLE_PWM ;   // Disable pin 3 PWM output
  delayMicroseconds ( us );
}

/**
 * \par Function
 *    enableIROut
 * \par Description
 *    Enable an IR for the specified number of khz.
 * \param[in]
 *    us - THe time of a INTR.
 * \par Output
 *    None
 * \par Return
 *    None
 * \par Others
 *    None
 */
void   IRremote :: enableIROut ( uint8_t khz )
{
  TIMER_DISABLE_INTR ;   //Timer2 disable Interrupt
  TIMER_CONFIG_KHZ ( khz );
}

/**
 * \par Function
 *    enableIRIn
 * \par Description
 *    Enable an IR to write in.
 * \param[in]
 *    None
 * \par Output
 *    None
 * \par Return
 *    None
 * \par Others
 *    None
 */
// initialization
void   IRremote :: enableIRIn ()   {
  cli ();
   // setup pulse clock timer interrupt
   //Prescale /8 (16M/8 = 0.5 microseconds per tick)
   // Therefore, the timer interval can range from 0.5 to 128 microseconds
   // depending on the reset value (255 to 0)
  TIMER_CONFIG_NORMAL ();

   //Timer2 Overflow Interrupt Enable
  TIMER_ENABLE_INTR ;

   //TIMER_RESET;

  sei ();    // enable interrupts

   // initialize state machine variables
  irparams . rcvstate  =  STATE_IDLE ;
  irparams . rawlen  =   0 ;

   // set pin modes
  pinMode ( irparams . recvpin ,  INPUT );
}

/**
 * \par Function
 *    sendRaw
 * \par Description
 *    Send the length of data with hz.
 * \param[in]
 *    buf[] - The data's buffer.
  * \param[in]
 *    len - The data's length.
  * \param[in]
 *    hz - The hz for sending data.
 * \par Output
 *    None
 * \par Return
 *    None
 * \par Others
 *    None
 */
void   IRremote :: sendRaw ( unsigned   int  buf [],   int  len ,  uint8_t hz )
{
  enableIROut ( hz );
   for   ( int  i  =   0 ;  i  <  len ;  i ++ )
   {
     if   ( &   1 )
     {
      space ( buf [ i ]);
     }  
     else
     {
      mark ( buf [ i ]);
     }
   }
  space ( 0 );   // Just to be sure
}

/**
 * \par Function
 *    getString
 * \par Description
 *    Get string in a INTR.
 * \param[in]
 *    None
 * \par Output
 *    None
 * \par Return
 *    Return the result in a IRQ.
 * \par Others
 *    None
 */
String   IRremote :: getString ()
{
   if ( decode ())
   {
    irRead  =   (( value   >>   8 )   >>   8 )   &   0xff ;
     if ( irRead  ==   0xa   ||  irRead  ==   0xd )
     {
      irIndex  =   0 ;
      irReady  =   true ;
     }
     else
     {
      irBuffer  +=  irRead ;  
      irIndex ++ ;
     }
    irDelayTime  =  millis ();
   }
   else
   {
     if ( irRead  >   0 )
     {
       if ( millis ()   -  irDelayTime  >   100 )
       {
        irPressed  =   false ;
        irRead  =   0 ;
        irDelayTime  =  millis ();
         Pre_Str   =   "" ;
       }
     }
   }
   if ( irReady )
   {
    irReady  =   false ;
     String  s  =   String ( irBuffer );
     Pre_Str   =  s ;
    irBuffer  =   "" ;
     return  s ;
   }
   return   Pre_Str ;
}

/**
 * \par Function
 *    getCode
 * \par Description
 *    Get the reading code.
 * \param[in]
 *    None
 * \par Output
 *    None
 * \par Return
 *    Return the result of reading.
 * \par Others
 *    None
 */
unsigned   char   IRremote :: getCode ()
{
  irIndex  =   0 ;
  loop ();
   return  irRead ;
}
String   IRremote :: getKeyMap ( byte keycode ,  byte ir_type )
{
   byte i ;
   ST_KEY_MAP  * irkeymap  =  normal_ir_keymap ;
    if   ( ir_type  ==  IR_TYPE_EM )  irkeymap  =  em_ir_keymap ;
    for   ( =   0 ;  i  <  KEY_MAX ;  i ++ )   {
         if   ( irkeymap [ i ]. keycode  ==  keycode )
         return  irkeymap [ i ]. keyname ;
    }
    return   "" ;
}

byte  IRremote :: getIrKey ( byte keycode ,  byte ir_type )
{
    byte i ;
    ST_KEY_MAP  * irkeymap  =  normal_ir_keymap ;
     if   ( ir_type  ==  IR_TYPE_EM )  irkeymap  =  em_ir_keymap ;
     for   ( =   0 ;  i  <  KEY_MAX ;  i ++ )   {
         if   ( irkeymap [ i ]. keycode  ==  keycode )
         return  i ;
     }
    return   0xFF ;
}
/**
 * \par Function
 *    sendString
 * \par Description
 *    Send data.
 * \param[in]
 *    s - The string you want to send.
 * \par Output
 *    None
 * \par Return
 *    None
 * \par Others
 *    None
 */
void   IRremote :: sendString ( String  s )
{
   unsigned   long  l ;
  uint8_t data ;
  s . concat ( '\n' );
   for ( int  i  =   0 ; <  s . length (); i ++ )
   {
    data  =  s . charAt ( i );
    l  =   0x0000ffff   &   ( uint8_t )( ~ data );
    l  =  l  <<   8 ;
    l  =  l  +   (( uint8_t ) data );
    l  =  l  <<   16 ;
    l  =  l  |   0x000000ff ;
    sendNEC ( l , 32 );
    delay ( 20 );
   }
  enableIRIn ();
}

/**
 * \par Function
 *    sendString
 * \par Description
 *    Send data.
 * \param[in]
 *    v - The string you want to send.
 * \par Output
 *    None
 * \par Return
 *    None
 * \par Others
 *    None
 */
void   IRremote :: sendString ( float  v )
{
  dtostrf ( v , 5 ,   8 ,  floatString );
  sendString ( floatString );
}

/**
 * \par Function
 *    sendNEC
 * \par Description
 *    Send NEC.
 * \param[in]
 *    data - The data you want to send.
  * \param[in]
 *    nbits - The data bit you want to send.
 * \par Output
 *    None
 * \par Return
 *    None
 * \par Others
 *    None
 */
void   IRremote :: sendNEC ( unsigned   long  data ,   int  nbits )
{
  
  enableIROut ( 38 );
  mark ( NEC_HDR_MARK );
  space ( NEC_HDR_SPACE );
   for   ( int  i  =   0 ;  i  <  nbits ;  i ++ )
   {
     if   ( data  &   1 )  
     {
      mark ( NEC_BIT_MARK );
      space ( NEC_ONE_SPACE );
     }  
     else  
     {
      mark ( NEC_BIT_MARK );
      space ( NEC_ZERO_SPACE );
     }
    data  >>=   1 ;
   }
  mark ( NEC_BIT_MARK );
  space ( 0 );
}

/**
 * \par Function
 *    loop
 * \par Description
 *    A circle of operation.
 * \param[in]
 *    None
 * \par Output0
 *    None
 * \par Return
 *    None
 * \par Others
 *    None
 */
void   IRremote :: loop ()
{
   if ( decode ())
   {
    irRead  =   (( value   >>   8 )   >>   8 )   &   0xff ;
    irPressed  =   true ;
     if ( irRead  ==   0xa   ||  irRead  ==   0xd )
     {
      irIndex  =   0 ;
      irReady  =   true ;
     }
     else
     {
      irBuffer  +=  irRead ;  
      irIndex ++ ;
       if ( irIndex  >   64 )
       {
        irIndex  =   0 ;
        irBuffer  =   "" ;
       }
     }
    irDelayTime  =   millis ();
   }
   else
   {
     if ( irRead  >   0 )
     {  
      // Serial.println(millis() - irDelayTime);
       if ( millis ()   -  irDelayTime  >   0 )
       {
        irPressed  =   false ;
        irRead  =   0 ;
        irDelayTime  =  millis ();
       }
     }
   }
  // Serial.println(irRead, HEX);
}

/**
 * \par Function
 *    keyPressed
 * \par Description
 *    Press key.
 * \param[in]
 *    None
 * \par Output
 *    None
 * \par Return
 *    Return you the pressed key or not.
 * \par Others
 *    None
 */
boolean  IRremote :: keyPressed ( unsigned   char  r )
{
  
  irIndex  =   0 ;
  loop ();
   return  irRead  ==  r ;
}
#endif   // !defined(__AVR_ATmega32U4__)

SHS/remote_control/IR_remote.h

#ifndef IRremote_h #define IRremote_h /* Includes ------------------------------------------------------------------*/ #include <stdint.h> #include <stdbool.h> #include <Arduino.h> #ifdef ME_PORT_DEFINED #endif // ME_PORT_DEFINED #ifndef __AVR_ATmega32U4__ #define MARK 0 #define SPACE 1 #define NEC_BITS 32 #define USECPERTICK 50 // microseconds per clock interrupt tick #define RAWBUF 80 // Length of raw duration buffer typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; #define NEC_HDR_MARK 9000 #define NEC_HDR_SPACE 4500 #define NEC_BIT_MARK 560 #define NEC_ONE_SPACE 1600 #define NEC_ZERO_SPACE 560 #define NEC_RPT_SPACE 2250 #define NEC_RPT_PERIOD 110000 #define _GAP 5000 // Minimum map between transmissions // receiver states #define STATE_IDLE 2 #define STATE_MARK 3 #define STATE_SPACE 4 #define STATE_STOP 5 // Values for decode_type #define NEC 1 #define SONY 2 #define RC5 3 #define RC6 4 #define DISH 5 #define SHARP 6 #define PANASONIC 7 #define JVC 8 #define SANYO 9 #define MITSUBISHI 10 #define SAMSUNG 11 #define LG 12 #define UNKNOWN -1 #define TOPBIT 0x80000000 #ifdef F_CPU #define SYSCLOCK F_CPU // main Arduino clock #else #define SYSCLOCK 16000000 // main Arduino clock #endif #define _GAP 5000 // Minimum map between transmissions #define GAP_TICKS (_GAP/USECPERTICK) #define TIMER_DISABLE_INTR (TIMSK2 = 0) #define TIMER_ENABLE_PWM (TCCR2A |= _BV(COM2B1)) #define TIMER_DISABLE_PWM (TCCR2A &= ~(_BV(COM2B1))) #define TIMER_ENABLE_INTR (TIMSK2 = _BV(OCIE2A)) #define TIMER_DISABLE_INTR (TIMSK2 = 0) #define TIMER_INTR_NAME TIMER2_COMPA_vect #define TIMER_CONFIG_KHZ(val) ({ \ const uint8_t pwmval = F_CPU / 2000 / (val); \ TCCR2A = _BV(WGM20); \ TCCR2B = _BV(WGM22) | _BV(CS20); \ OCR2A = pwmval; \ OCR2B = pwmval / 3; \ }) #define TIMER_COUNT_TOP (SYSCLOCK * USECPERTICK / 1000000) #if (TIMER_COUNT_TOP < 256) #define TIMER_CONFIG_NORMAL() ({ \ TCCR2A = _BV(WGM21); \ TCCR2B = _BV(CS20); \ OCR2A = TIMER_COUNT_TOP; \ TCNT2 = 0; \ }) #else #define TIMER_CONFIG_NORMAL() ({ \ TCCR2A = _BV(WGM21); \ TCCR2B = _BV(CS21); \ OCR2A = TIMER_COUNT_TOP / 8; \ TCNT2 = 0; \ }) #endif // information for the interrupt handler typedef struct { uint8_t recvpin; // pin for IR data from detector volatile uint8_t rcvstate; // state machine volatile uint32_t lastTime; unsigned int timer; // volatile uint8_t rawbuf[RAWBUF]; // raw data volatile uint8_t rawlen; // counter of entries in rawbuf } irparams_t; class IRremote { public: IRremote(int pin); ErrorStatus decode(); void begin(); void end(); void loop(); boolean keyPressed(unsigned char r); // void resume(); int8_t decode_type; // NEC, SONY, RC5, UNKNOWN unsigned long value; // Decoded value uint8_t bits; // Number of bits in decoded value volatile uint8_t *rawbuf; // Raw intervals in .5 us ticks int rawlen; // Number of records in rawbuf. String getString(); unsigned char getCode(); String getKeyMap(byte keycode, byte ir_type = 1); byte getIrKey(byte keycode, byte ir_type = 1); void sendString(String s); void sendString(float v); void sendNEC(unsigned long data, int nbits); void sendRaw(unsigned int buf[], int len, uint8_t hz); void enableIROut(uint8_t khz); void enableIRIn(); void mark(uint16_t us); void space(uint16_t us); private: ErrorStatus decodeNEC(); int16_t irIndex; char irRead; char floatString[5]; boolean irReady; boolean irPressed; String irBuffer; String Pre_Str; double irDelayTime; }; #endif // !__AVR_ATmega32U4__ #endif

SHS/remote_control/Keymap.cpp

#include "Keymap.h" ST_KEY_MAP normal_ir_keymap[18] = { {"1", 0x45}, {"2", 0x46}, {"3", 0x47}, {"4", 0x44}, {"5", 0x40}, {"6", 0x43}, {"7", 0x07}, {"8", 0x15}, {"9", 0x09}, {"0", 0x19}, {"*", 0x16}, {"#", 0x0D}, {"up", 0x18}, {"down", 0x52}, {"ok", 0x1C}, {"left", 0x08}, {"right", 0x5A} }; ST_KEY_MAP em_ir_keymap[21] = { {"A", 0x45}, {"B", 0x46}, {"C", 0x47}, {"D", 0x44}, {"up", 0x40}, {"+", 0x43}, {"left", 0x07}, {"ok", 0x15}, {"right", 0x09}, {"0", 0x16}, {"down", 0x19}, {"-", 0x0d}, {"1", 0x0c}, {"2", 0x18}, {"3", 0x5e}, {"4", 0x08}, {"5", 0x1c}, {"6", 0x5A}, {"7", 0x42}, {"8", 0x52}, {"9", 0x4A} };

SHS/remote_control/Keymap.h

#ifndef _KEYMAY_H_ #define _KEYMAY_H_ #include <Arduino.h> #define KEY_MAX 21 typedef struct { String keyname; byte keycode; }ST_KEY_MAP; #define IR_TYPE_NORMAL 1 #define IR_TYPE_EM 2 typedef enum { IR_KEYCODE_1 = 0, IR_KEYCODE_2, IR_KEYCODE_3, IR_KEYCODE_4, IR_KEYCODE_5, IR_KEYCODE_6, IR_KEYCODE_7, IR_KEYCODE_8, IR_KEYCODE_9, IR_KEYCODE_0, IR_KEYCODE_STAR, // * IR_KEYCODE_POUND, // # IR_KEYCODE_UP, IR_KEYCODE_DOWN, IR_KEYCODE_OK, IR_KEYCODE_LEFT, IR_KEYCODE_RIGHT, }E_NORMAL_IR_KEYCODE; typedef enum { EM_IR_KEYCODE_A = 0, EM_IR_KEYCODE_B, EM_IR_KEYCODE_C, EM_IR_KEYCODE_D, EM_IR_KEYCODE_UP, EM_IR_KEYCODE_PLUS, EM_IR_KEYCODE_LEFT, EM_IR_KEYCODE_OK, EM_IR_KEYCODE_RIGHT, EM_IR_KEYCODE_0, EM_IR_KEYCODE_DOWN, EM_IR_KEYCODE_REDUCE, EM_IR_KEYCODE_1, EM_IR_KEYCODE_2, EM_IR_KEYCODE_3, EM_IR_KEYCODE_4, EM_IR_KEYCODE_5, EM_IR_KEYCODE_6, EM_IR_KEYCODE_7, EM_IR_KEYCODE_8, EM_IR_KEYCODE_9 }E_EM_IR_KEYCODE; extern ST_KEY_MAP normal_ir_keymap[]; extern ST_KEY_MAP em_ir_keymap[]; #endif /* _KEYMAY_H_ */

SHS/remote_control/PH20Port.cpp

#include "PH20Port.h" PH20Port_Sig PH20_Port[RJ25_MAX] = { { A3, NC, NC, NC, NC, NC }, //1 { A2, NC, NC, NC, NC, NC }, //2 { A1, NC, NC, NC, NC, NC }, //3 { A0, NC, NC, NC, NC, NC }, //4 { 7, A0, NC, NC, NC, NC }, //5 { 8, A1, NC, NC, NC, NC }, //6 { A5, A4, NC, NC, NC, NC }, //7 { 6, 5, NC, NC, NC, NC }, //8 { 3, NC, NC, NC, NC, NC }, //9 { 4, NC, NC, NC, NC, NC }, //10 { 5, NC, NC, NC, NC, NC }, //11 { 6, NC, NC, NC, NC, NC }, //12 { 4, 7, 8, A3, NC, NC }, //13 { 2, 7, A5, A4, NC, NC }, //14 { NC, NC, 3, 5, 6, NC }, //15 { NC, NC, A4, A5, 2, NC }, //16 }; /***********************Port*********************/ /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here */ PH20Port::PH20Port(void) { s1 = PH20_Port[0].s1; s2 = PH20_Port[0].s2; s3 = PH20_Port[0].s3; s4 = PH20_Port[0].s4; s5 = PH20_Port[0].s5; s6 = PH20_Port[0].s6; _port = 0; } /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here, but PWM frequency set to 976 Hz * \param[in] * port - RJ25 port from PORT_1 to M2 */ PH20Port::PH20Port(uint8_t port) { if (port < 1) return; s1 = PH20_Port[port-1].s1; s2 = PH20_Port[port-1].s2; s3 = PH20_Port[port-1].s3; s4 = PH20_Port[port-1].s4; s5 = PH20_Port[port-1].s5; s6 = PH20_Port[port-1].s6; _port = port; } /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here, but PWM frequency set to 976 Hz * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 */ PH20Port::PH20Port(uint8_t port, uint8_t slot) { if (port < 1) return; s1 = PH20_Port[port-1].s1; s2 = PH20_Port[port-1].s2; _port = port; _slot = slot; } /** * \par Function * getPort * \par Description * Get current valid port of current RJ25 object * \par Output * None * \return * Port bumber from PORT_1 to M2 * \par Others * None */ uint8_t PH20Port::getPort() { return(_port); } /** * \par Function * getSlot * \par Description * Get current valid slot of current RJ25 object's port * \par Output * None * \return * Slot bumber SLOT1 or SLOT2 * \par Others * None */ uint8_t PH20Port::getSlot(void) { return(_slot); } /** * \par Function * dRead1 * \par Description * Read the digital input value on slot1 of current RJ25 object's port * \param[in] * mode - digital input mode INPUT or INPUT_PULLUP * \par Output * None * \return * Digital input value * \par Others * None */ bool PH20Port::dRead1(uint8_t mode) { bool val; pinMode(s1, mode); val = digitalRead(s1); return(val); } /** * \par Function * dRead2 * \par Description * Read the digital input value on slot2 of current RJ25 object's port * \param[in] * mode - digital input mode INPUT or INPUT_PULLUP * \par Output * None * \return * Digital input value * \par Others * None */ bool PH20Port::dRead2(uint8_t mode) { bool val; pinMode(s2, mode); val = digitalRead(s2); return(val); } bool PH20Port::dRead3(uint8_t mode) { bool val; pinMode(s3, mode); val = digitalRead(s3); return(val); } bool PH20Port::dRead4(uint8_t mode) { bool val; pinMode(s4, mode); val = digitalRead(s4); return(val); } bool PH20Port::dRead5(uint8_t mode) { bool val; pinMode(s5, mode); val = digitalRead(s5); return(val); } /** * \par Function * dpRead1 * \par Description * Read the digital input value on slot1 of current RJ25 object's port, the input * mode set as INPUT_PULLUP. * \par Output * None * \return * Digital input value * \par Others * None */ bool PH20Port::dpRead1(void) { bool val; pinMode(s1, INPUT_PULLUP); val = digitalRead(s1); return(val); } /** * \par Function * dpRead2 * \par Description * Read the digital input value on slot2 of current RJ25 object's port, the input * mode set as INPUT_PULLUP. * \par Output * None * \return * Digital input value * \par Others * None */ bool PH20Port::dpRead2(void) { bool val; pinMode(s2, INPUT_PULLUP); val = digitalRead(s2); return(val); } /** * \par Function * dWrite1 * \par Description * Set the digital output value on slot1 of current RJ25 object's port * \param[in] * value - digital output value HIGH or LOW * \par Output * None * \return * None * \par Others * None */ void PH20Port::dWrite1(bool value) { pinMode(s1, OUTPUT); digitalWrite(s1, value); } /** * \par Function * dWrite2 * \par Description * Set the digital output value on slot2 of current RJ25 object's port * \param[in] * value - digital output value HIGH or LOW * \par Output * None * \return * None * \par Others * None */ void PH20Port::dWrite2(bool value) { pinMode(s2, OUTPUT); digitalWrite(s2, value); } void PH20Port::dWrite3(bool value) { pinMode(s3, OUTPUT); digitalWrite(s3, value); } void PH20Port::dWrite4(bool value) { pinMode(s4, OUTPUT); digitalWrite(s4, value); } void PH20Port::dWrite5(bool value) { pinMode(s5, OUTPUT); digitalWrite(s5, value); } /** * \par Function * aRead1 * \par Description * Read the analog value on slot1 of current RJ25 object's port * \par Output * None * \return * Analog value from 0-1023 * \par Others * None */ int16_t PH20Port::aRead1(void) { int16_t val; pinMode(s1, INPUT); val = analogRead(s1); return(val); } /** * \par Function * aRead2 * \par Description * Read the analog value on slot2 of current RJ25 object's port * \par Output * None * \return * Analog value from 0-1023 * \par Others * None */ int16_t PH20Port::aRead2(void) { int16_t val; pinMode(s2, INPUT); val = analogRead(s2); return(val); } int16_t PH20Port::aRead3(void) { int16_t val; pinMode(s3, INPUT); val = analogRead(s3); return(val); } int16_t PH20Port::aRead4(void) { int16_t val; pinMode(s4, INPUT); val = analogRead(s4); return(val); } int16_t PH20Port::aRead5(void) { int16_t val; pinMode(s5, INPUT); val = analogRead(s5); return(val); } /** * \par Function * aWrite1 * \par Description * Set the PWM output value on slot1 of current RJ25 object's port * \param[in] * value - Analog value between 0 to 255 * \par Output * None * \return * None * \par Others * None */ void PH20Port::aWrite1(int16_t value) { analogWrite(s1, value); } /** * \par Function * aWrite2 * \par Description * Set the PWM output value on slot2 of current RJ25 object's port * \param[in] * value - Analog value between 0 to 255 * \par Output * None * \return * None * \par Others * None */ void PH20Port::aWrite2(int16_t value) { analogWrite(s2, value); } void PH20Port::aWrite3(int16_t value) { analogWrite(s3, value); } void PH20Port::aWrite4(int16_t value) { analogWrite(s4, value); } void PH20Port::aWrite5(int16_t value) { analogWrite(s5, value); } /** * \par Function * reset * \par Description * Reset the RJ25 available PIN by its port * \param[in] * port - RJ25 port from PORT_1 to M2 * \par Output * None * \return * None * \par Others * None */ void PH20Port::reset(uint8_t port) { if ( port < 1) return; s1 = PH20_Port[port-1].s1; s2 = PH20_Port[port-1].s2; _port = port; } /** * \par Function * reset * \par Description * Reset the RJ25 available PIN by its port and slot * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 * \par Output * None * \return * None * \par Others * None */ void PH20Port::reset(uint8_t port, uint8_t slot) { if ( port < 1) return; s1 = PH20_Port[port-1].s1; s2 = PH20_Port[port-1].s2; _port = port; _slot = slot; } /** * \par Function * pin1 * \par Description * Return the arduino pin number of current RJ25 object's slot1 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t PH20Port::pin1(void) { return(s1); } /** * \par Function * pin2 * \par Description * Return the arduino pin number of current RJ25 object's slot2 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t PH20Port::pin2(void) { return(s2); } uint8_t PH20Port::pin3(void) { return(s3); } uint8_t PH20Port::pin4(void) { return(s4); } uint8_t PH20Port::pin5(void) { return(s5); } /** * \par Function * pin * \par Description * Return the arduino pin number of current RJ25 object's port, if the RJ25 module * have one available PIN. * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t PH20Port::pin(void) { return(_slot == SLOT_1 ? s1 : s2); } /** * \par Function * pin * \par Description * Return the arduino pin number of current RJ25 object's port * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t PH20Port::pin(uint8_t port, uint8_t slot) { if ( port < 1) return; return(slot == SLOT_1 ? PH20_Port[port-1].s1 : PH20_Port[port-1].s2); }

SHS/remote_control/PH20Port.h

#ifndef _PH20Port_H_ #define _PH20Port_H_ #include <Arduino.h> #include <avr/interrupt.h> #include <avr/io.h> #include <util/delay.h> #include <stdint.h> #include <stdlib.h> #define RJ25_MAX 16 #define P1 1 #define P2 2 #define P3 3 #define P4 4 #define P5 5 #define P6 6 #define P7 7 #define P8 8 #define P9 9 #define P10 10 #define P11 11 #define P12 12 #define P13 13 #define P14 14 #define P15 15 #define P16 16 /** * A structure to represent PH20Port Signal. */ typedef struct { uint8_t s1; uint8_t s2; uint8_t s3; uint8_t s4; uint8_t s5; uint8_t s6; } PH20Port_Sig; extern PH20Port_Sig PH20_Port[RJ25_MAX]; // PH20Port[0] is nonsense #define NC (0) //use UART RX for NULL port #define SLOT1 (1) #define SLOT2 (2) #define SLOT3 (3) #define SLOT4 (4) #define SLOT5 (5) #define SLOT6 (6) #define SLOT_1 SLOT1 #define SLOT_2 SLOT2 #define SLOT_3 SLOT3 #define SLOT_4 SLOT4 #define SLOT_5 SLOT3 #define SLOT_6 SLOT4 #ifndef FALSE #define FALSE (0) #endif #ifndef TRUE #define TRUE (1) #endif /** * Class: PH20Port * * \par Description * Declaration of Class PH20Port */ class PH20Port { public: /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here */ PH20Port(void); /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here, but PWM frequency set to 976 Hz * \param[in] * port - RJ25 port from PORT_1 to M2 */ PH20Port(uint8_t port); /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here, but PWM frequency set to 976 Hz * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 */ PH20Port(uint8_t port, uint8_t slot); /** * \par Function * getPort * \par Description * Get current valid port of current RJ25 object * \par Output * None * \return * Port bumber from PORT_1 to M2 * \par Others * None */ uint8_t getPort(void); /** * \par Function * getSlot * \par Description * Get current valid slot of current RJ25 object's port * \par Output * None * \return * Slot bumber SLOT1 or SLOT2 * \par Others * None */ uint8_t getSlot(void); /** * \par Function * dRead1 * \par Description * Read the digital input value on slot1 of current RJ25 object's port * \param[in] * mode - digital input mode INPUT or INPUT_PULLUP * \par Output * None * \return * Digital input value * \par Others * None */ bool dRead1(uint8_t mode = INPUT); /** * \par Function * dRead2 * \par Description * Read the digital input value on slot2 of current RJ25 object's port * \param[in] * mode - digital input mode INPUT or INPUT_PULLUP * \par Output * None * \return * Digital input value * \par Others * None */ bool dRead2(uint8_t mode = INPUT); bool dRead3(uint8_t mode = INPUT); bool dRead4(uint8_t mode = INPUT); bool dRead5(uint8_t mode = INPUT); /** * \par Function * dpRead1 * \par Description * Read the digital input value on slot1 of current RJ25 object's port, the input * mode set as INPUT_PULLUP. * \par Output * None * \return * Digital input value * \par Others * None */ bool dpRead1(void); /** * \par Function * dpRead2 * \par Description * Read the digital input value on slot2 of current RJ25 object's port, the input * mode set as INPUT_PULLUP. * \par Output * None * \return * Digital input value * \par Others * None */ bool dpRead2(void); /** * \par Function * dWrite1 * \par Description * Set the digital output value on slot1 of current RJ25 object's port * \param[in] * value - digital output value HIGH or LOW * \par Output * None * \return * None * \par Others * None */ void dWrite1(bool value); /** * \par Function * dWrite2 * \par Description * Set the digital output value on slot2 of current RJ25 object's port * \param[in] * value - digital output value HIGH or LOW * \par Output * None * \return * None * \par Others * None */ void dWrite2(bool value); void dWrite3(bool value); void dWrite4(bool value); void dWrite5(bool value); /** * \par Function * aRead1 * \par Description * Read the analog value on slot1 of current RJ25 object's port * \par Output * None * \return * Analog value from 0-1023 * \par Others * None */ int16_t aRead1(void); /** * \par Function * aRead2 * \par Description * Read the analog value on slot2 of current RJ25 object's port * \par Output * None * \return * Analog value from 0-1023 * \par Others * None */ int16_t aRead2(void); int16_t aRead3(void); int16_t aRead4(void); int16_t aRead5(void); /** * \par Function * aWrite1 * \par Description * Set the PWM output value on slot1 of current RJ25 object's port * \param[in] * value - Analog value between 0 to 255 * \par Output * None * \return * None * \par Others * None */ void aWrite1(int16_t value); /** * \par Function * aWrite2 * \par Description * Set the PWM output value on slot2 of current RJ25 object's port * \param[in] * value - Analog value between 0 to 255 * \par Output * None * \return * None * \par Others * None */ void aWrite2(int16_t value); void aWrite3(int16_t value); void aWrite4(int16_t value); void aWrite5(int16_t value); /** * \par Function * reset * \par Description * Reset the RJ25 available PIN by its port * \param[in] * port - RJ25 port from PORT_1 to M2 * \par Output * None * \return * None * \par Others * None */ void reset(uint8_t port); /** * \par Function * reset * \par Description * Reset the RJ25 available PIN by its port and slot * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 * \par Output * None * \return * None * \par Others * None */ void reset(uint8_t port, uint8_t slot); /** * \par Function * pin1 * \par Description * Return the arduino pin number of current RJ25 object's slot1 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t pin1(void); /** * \par Function * pin2 * \par Description * Return the arduino pin number of current RJ25 object's slot2 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t pin2(void); uint8_t pin3(void); uint8_t pin4(void); uint8_t pin5(void); /** * \par Function * pin * \par Description * Return the arduino pin number of current RJ25 object's port, if the RJ25 module * have one available PIN. * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t pin(void); /** * \par Function * pin * \par Description * Return the arduino pin number of current RJ25 object's port * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t pin(uint8_t port, uint8_t slot); protected: /** * \par Description * Variables used to store the slot1 gpio number */ uint8_t s1, s2, s3, s4, s5, s6; /** * \par Description * Variables used to store the port */ uint8_t _port; /** * \par Description * Variables used to store the slot */ uint8_t _slot; }; #endif // _RH20Port_H_

SHS/remote_control/remote_control.ino

#include "IR_remote.h" #include "keymap.h" IRremote ir(4); #include <Servo.h> Servo servo_12; Servo servo_13; void setup(){ ir.begin(); pinMode(5, OUTPUT); pinMode(6, OUTPUT); servo_12.attach(12); servo_13.attach(13); } void loop(){ if (ir.getIrKey(ir.getCode(),2) == EM_IR_KEYCODE_1) { digitalWrite(5,HIGH); digitalWrite(6,LOW); } if (ir.getIrKey(ir.getCode(),2) == EM_IR_KEYCODE_2) { digitalWrite(5,LOW); digitalWrite(6,LOW); } if (ir.getIrKey(ir.getCode(),2) == EM_IR_KEYCODE_4) { servo_12.write(90); delay(20); } if (ir.getIrKey(ir.getCode(),2) == EM_IR_KEYCODE_3) { servo_12.write(0); delay(20); } if (ir.getIrKey(ir.getCode(),2) == EM_IR_KEYCODE_6) { servo_13.write(90); delay(20); } if (ir.getIrKey(ir.getCode(),2) == EM_IR_KEYCODE_5) { servo_13.write(0); delay(20); } }

SHS/Temperature_and_humidity/Adafruit_Sensor.cpp

#include "Adafruit_Sensor.h" /**************************************************************************/ /*! @brief Prints sensor information to serial console */ /**************************************************************************/ void Adafruit_Sensor::printSensorDetails(void) { sensor_t sensor; getSensor(&sensor); Serial.println(F("------------------------------------")); Serial.print(F("Sensor: ")); Serial.println(sensor.name); Serial.print(F("Type: ")); switch ((sensors_type_t)sensor.type) { case SENSOR_TYPE_ACCELEROMETER: Serial.print(F("Acceleration (m/s2)")); break; case SENSOR_TYPE_MAGNETIC_FIELD: Serial.print(F("Magnetic (uT)")); break; case SENSOR_TYPE_ORIENTATION: Serial.print(F("Orientation (degrees)")); break; case SENSOR_TYPE_GYROSCOPE: Serial.print(F("Gyroscopic (rad/s)")); break; case SENSOR_TYPE_LIGHT: Serial.print(F("Light (lux)")); break; case SENSOR_TYPE_PRESSURE: Serial.print(F("Pressure (hPa)")); break; case SENSOR_TYPE_PROXIMITY: Serial.print(F("Distance (cm)")); break; case SENSOR_TYPE_GRAVITY: Serial.print(F("Gravity (m/s2)")); break; case SENSOR_TYPE_LINEAR_ACCELERATION: Serial.print(F("Linear Acceleration (m/s2)")); break; case SENSOR_TYPE_ROTATION_VECTOR: Serial.print(F("Rotation vector")); break; case SENSOR_TYPE_RELATIVE_HUMIDITY: Serial.print(F("Relative Humidity (%)")); break; case SENSOR_TYPE_AMBIENT_TEMPERATURE: Serial.print(F("Ambient Temp (C)")); break; case SENSOR_TYPE_OBJECT_TEMPERATURE: Serial.print(F("Object Temp (C)")); break; case SENSOR_TYPE_VOLTAGE: Serial.print(F("Voltage (V)")); break; case SENSOR_TYPE_CURRENT: Serial.print(F("Current (mA)")); break; case SENSOR_TYPE_COLOR: Serial.print(F("Color (RGBA)")); break; } Serial.println(); Serial.print(F("Driver Ver: ")); Serial.println(sensor.version); Serial.print(F("Unique ID: ")); Serial.println(sensor.sensor_id); Serial.print(F("Min Value: ")); Serial.println(sensor.min_value); Serial.print(F("Max Value: ")); Serial.println(sensor.max_value); Serial.print(F("Resolution: ")); Serial.println(sensor.resolution); Serial.println(F("------------------------------------\n")); }

SHS/Temperature_and_humidity/Adafruit_Sensor.h

/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software< /span> * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Update by K. Townsend (Adafruit Industries) for lighter typedefs, and * extended sensor support to include color, voltage and current */ #ifndef _ADAFRUIT_SENSOR_H #define _ADAFRUIT_SENSOR_H #ifndef ARDUINO #include <stdint.h> #elif ARDUINO >= 100 #include "Arduino.h" #include "Print.h" #else #include "WProgram.h" #endif /* Constants */ #define SENSORS_GRAVITY_EARTH (9.80665F) /**< Earth's gravity in m/s^2 */ #define SENSORS_GRAVITY_MOON (1.6F) /**< The moon's gravity in m/s^2 */ #define SENSORS_GRAVITY_SUN (275.0F) /**< The sun's gravity in m/s^2 */ #define SENSORS_GRAVITY_STANDARD (SENSORS_GRAVITY_EARTH) #define SENSORS_MAGFIELD_EARTH_MAX \ (60.0F) /**< Maximum magnetic field on Earth's surface */ #define SENSORS_MAGFIELD_EARTH_MIN \ (30.0F) /**< Minimum magnetic field on Earth's surface */ #define SENSORS_PRESSURE_SEALEVELHPA \ (1013.25F) /**< Average sea level pressure is 1013.25 hPa */ #define SENSORS_DPS_TO_RADS \ (0.017453293F) /**< Degrees/s to rad/s multiplier \ */ #define SENSORS_RADS_TO_DPS \ (57.29577793F) /**< Rad/s to degrees/s multiplier */ #define SENSORS_GAUSS_TO_MICROTESLA \ (100) /**< Gauss to micro-Tesla multiplier */ /** Sensor types */ typedef enum { SENSOR_TYPE_ACCELEROMETER = (1), /**< Gravity + linear acceleration */ SENSOR_TYPE_MAGNETIC_FIELD = (2), SENSOR_TYPE_ORIENTATION = (3), SENSOR_TYPE_GYROSCOPE = (4), SENSOR_TYPE_LIGHT = (5), SENSOR_TYPE_PRESSURE = (6), SENSOR_TYPE_PROXIMITY = (8), SENSOR_TYPE_GRAVITY = (9), SENSOR_TYPE_LINEAR_ACCELERATION = (10), /**< Acceleration not including gravity */ SENSOR_TYPE_ROTATION_VECTOR = (11), SENSOR_TYPE_RELATIVE_HUMIDITY = (12), SENSOR_TYPE_AMBIENT_TEMPERATURE = (13), SENSOR_TYPE_OBJECT_TEMPERATURE = (14), SENSOR_TYPE_VOLTAGE = (15), SENSOR_TYPE_CURRENT = (16), SENSOR_TYPE_COLOR = (17) } sensors_type_t; /** struct sensors_vec_s is used to return a vector in a common format. */ typedef struct { union { float v[3]; ///< 3D vector elements struct { float x; ///< X component of vector float y; ///< Y component of vector float z; ///< Z component of vector }; ///< Struct for holding XYZ component /* Orientation sensors */ struct { float roll; /**< Rotation around the longitudinal axis (the plane body, 'X axis'). Roll is positive and increasing when moving downward. -90 degrees <= roll <= 90 degrees */ float pitch; /**< Rotation around the lateral axis (the wing span, 'Y axis'). Pitch is positive and increasing when moving upwards. -180 degrees <= pitch <= 180 degrees) */ float heading; /**< Angle between the longitudinal axis (the plane body) and magnetic north, measured clockwise when viewing from the top of the device. 0-359 degrees */ }; ///< Struct for holding roll/pitch/heading }; ///< Union that can hold 3D vector array, XYZ components or ///< roll/pitch/heading int8_t status; ///< Status byte uint8_t reserved[3]; ///< Reserved } sensors_vec_t; /** struct sensors_color_s is used to return color data in a common format. */ typedef struct { union { float c[3]; ///< Raw 3-element data /* RGB color space */ struct { float r; /**< Red component */ float g; /**< Green component */ float b; /**< Blue component */ }; ///< RGB data in floating point notation }; ///< Union of various ways to describe RGB colorspace uint32_t rgba; /**< 24-bit RGBA value */ } sensors_color_t; /* Sensor event (36 bytes) */ /** struct sensor_event_s is used to provide a single sensor event in a common * format. */ typedef struct { int32_t version; /**< must be sizeof(struct sensors_event_t) */ int32_t sensor_id; /**< unique sensor identifier */ int32_t type; /**< sensor type */ int32_t reserved0; /**< reserved */ int32_t timestamp; /**< time is in milliseconds */ union { float data[4]; ///< Raw data sensors_vec_t acceleration; /**< acceleration values are in meter per second per second (m/s^2) */ sensors_vec_t magnetic; /**< magnetic vector values are in micro-Tesla (uT) */ sensors_vec_t orientation; /**< orientation values are in degrees */ sensors_vec_t gyro; /**< gyroscope values are in rad/s */ float temperature; /**< temperature is in degrees centigrade (Celsius) */ float distance; /**< distance in centimeters */ float light; /**< light in SI lux units */ float pressure; /**< pressure in hectopascal (hPa) */ float relative_humidity; /**< relative humidity in percent */ float current; /**< current in milliamps (mA) */ float voltage; /**< voltage in volts (V) */ sensors_color_t color; /**< color in RGB component values */ }; ///< Union for the wide ranges of data we can carry } sensors_event_t; /* Sensor details (40 bytes) */ /** struct sensor_s is used to describe basic information about a specific * sensor. */ typedef struct { char name[12]; /**< sensor name */ int32_t version; /**< version of the hardware + driver */ int32_t sensor_id; /**< unique sensor identifier */ int32_t type; /**< this sensor's type (ex. SENSOR_TYPE_LIGHT) */ float max_value; /**< maximum value of this sensor's value in SI units */ float min_value; /**< minimum value of this sensor's value in SI units */ float resolution; /**< smallest difference between two values reported by this sensor */ int32_t min_delay; /**< min delay in microseconds between events. zero = not a constant rate */ } sensor_t; /** @brief Common sensor interface to unify various sensors. * Intentionally modeled after sensors.h in the Android API: * https://github.com/android/platform_hardware_libhardware/blob/master/include/hardware/sensors.h */ class Adafruit_Sensor { public: // Constructor(s) Adafruit_Sensor() {} virtual ~Adafruit_Sensor() {} // These must be defined by the subclass /*! @brief Whether we should automatically change the range (if possible) for higher precision @param enabled True if we will try to autorange */ virtual void enableAutoRange(bool enabled) { (void)enabled; /* suppress unused warning */ }; /*! @brief Get the latest sensor event @returns True if able to fetch an event */ virtual bool getEvent(sensors_event_t *) = 0; /*! @brief Get info about the sensor itself */ virtual void getSensor(sensor_t *) = 0; void printSensorDetails(void); private: bool _autoRange; }; #endif

SHS/Temperature_and_humidity/DHT.cpp

SHS/Temperature_and_humidity/DHT.cpp

/*!
 *  @file DHT.cpp
 *
 *  @mainpage DHT series of low cost temperature/humidity sensors.
 *
 *  @section intro_sec Introduction
 *
 *  This is a library for DHT series of low cost temperature/humidity sensors.
 *
 *  You must have Adafruit Unified Sensor Library library installed to use this
 * class.
 *
 *  Adafruit invests time and resources providing this open source code,
 *  please support Adafruit andopen-source hardware by purchasing products
 *  from Adafruit!
 *
 *  @section author Author
 *
 *  Written by Adafruit Industries.
 *
 *  @section license License
 *
 *  MIT license, all text above must be included in any redistribution
 */

#include   "DHT.h"

#define  MIN_INTERVAL  2000   /**< min interval value */
#define  TIMEOUT                                                                \
  UINT32_MAX  /**< Used programmatically for timeout.                           \
                   Not a timeout duration. Type: uint32_t. */

/*!
 *  @brief  Instantiates a new DHT class
 *  @param  pin
 *          pin number that sensor is connected
 *  @param  type
 *          type of sensor
 *  @param  count
 *          number of sensors
 */
DHT :: DHT ( uint8_t pin ,  uint8_t type ,  uint8_t count )   {
   ( void ) count ;   // Workaround to avoid compiler warning.
  _pin  =  pin ;
  _type  =  type ;
#ifdef  __AVR
  _bit  =  digitalPinToBitMask ( pin );
  _port  =  digitalPinToPort ( pin );
#endif
  _maxcycles  =
      microsecondsToClockCycles ( 1000 );   // 1 millisecond timeout for
                                        // reading pulses from DHT sensor.
   // Note that count is now ignored as the DHT reading algorithm adjusts itself
   // based on the speed of the processor.
}

/*!
 *  @brief  Setup sensor pins and set pull timings
 *  @param  usec
 *          Optionally pass pull-up time (in microseconds) before DHT reading
 *starts. Default is 55 (see function declaration in DHT.h).
 */
void  DHT :: begin ( uint8_t usec )   {
   // set up the pins!
  pinMode ( _pin ,  INPUT_PULLUP );
   // Using this value makes sure that millis() - lastreadtime will be
   // >= MIN_INTERVAL right away. Note that this assignment wraps around,
   // but so will the subtraction.
  _lastreadtime  =  millis ()   -  MIN_INTERVAL ;
  DEBUG_PRINT ( "DHT max clock cycles: " );
  DEBUG_PRINTLN ( _maxcycles ,  DEC );
  pullTime  =  usec ;
}

/*!
 *  @brief  Read temperature
 *  @param  S
 *          Scale. Boolean value:
 *                  - true = Fahrenheit
 *                  - false = Celcius
 *  @param  force
 *          true if in force mode
 *  @return Temperature value in selected scale
 */
float  DHT :: readTemperature ( bool  S ,   bool  force )   {
   float  f  =  NAN ;

   if   ( read ( force ))   {
     switch   ( _type )   {
     case  DHT11 :
      f  =  data [ 2 ];
       if   ( data [ 3 ]   &   0x80 )   {
        f  =   - 1   -  f ;
       }
      f  +=   ( data [ 3 ]   &   0x0f )   *   0.1 ;
       if   ( S )   {
        f  =  convertCtoF ( f );
       }
       break ;
     case  DHT12 :
      f  =  data [ 2 ];
      f  +=   ( data [ 3 ]   &   0x0f )   *   0.1 ;
       if   ( data [ 2 ]   &   0x80 )   {
        f  *=   - 1 ;
       }
       if   ( S )   {
        f  =  convertCtoF ( f );
       }
       break ;
     case  DHT22 :
     case  DHT21 :
      f  =   (( word )( data [ 2 ]   &   0x7F ))   <<   8   |  data [ 3 ];
      f  *=   0.1 ;
       if   ( data [ 2 ]   &   0x80 )   {
        f  *=   - 1 ;
       }
       if   ( S )   {
        f  =  convertCtoF ( f );
       }
       break ;
     }
   }
   return  f ;
}

/*!
 *  @brief  Converts Celcius to Fahrenheit
 *  @param  c
 *                  value in Celcius
 *  @return float value in Fahrenheit
 */
float  DHT :: convertCtoF ( float  c )   {   return  c  *   1.8   +   32 ;   }

/*!
 *  @brief  Converts Fahrenheit to Celcius
 *  @param  f
 *                  value in Fahrenheit
 *  @return float value in Celcius
 */
float  DHT :: convertFtoC ( float  f )   {   return   ( -   32 )   *   0.55555 ;   }

/*!
 *  @brief  Read Humidity
 *  @param  force
 *                  force read mode
 *  @return float value - humidity in percent
 */
float  DHT :: readHumidity ( bool  force )   {
   float  f  =  NAN ;
   if   ( read ( force ))   {
     switch   ( _type )   {
     case  DHT11 :
     case  DHT12 :
      f  =  data [ 0 ]   +  data [ 1 ]   *   0.1 ;
       break ;
     case  DHT22 :
     case  DHT21 :
      f  =   (( word ) data [ 0 ])   <<   8   |  data [ 1 ];
      f  *=   0.1 ;
       break ;
     }
   }
   return  f ;
}

/*!
 *  @brief  Compute Heat Index
 *          Simplified version that reads temp and humidity from sensor
 *  @param  isFahrenheit
 *                  true if fahrenheit, false if celcius
 *(default true)
 *  @return float heat index
 */
float  DHT :: computeHeatIndex ( bool  isFahrenheit )   {
   float  hi  =  computeHeatIndex ( readTemperature ( isFahrenheit ),  readHumidity (),
                              isFahrenheit );
   return  hi ;
}

/*!
 *  @brief  Compute Heat Index
 *                  Using both Rothfusz and Steadman's equations
 *                  (http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml)
 *  @param  temperature
 *          temperature in selected scale
 *  @param  percentHumidity
 *          humidity in percent
 *  @param  isFahrenheit
 *                  true if fahrenheit, false if celcius
 *  @return float heat index
 */
float  DHT :: computeHeatIndex ( float  temperature ,   float  percentHumidity ,
                             bool  isFahrenheit )   {
   float  hi ;

   if   ( ! isFahrenheit )
    temperature  =  convertCtoF ( temperature );

  hi  =   0.5   *   ( temperature  +   61.0   +   (( temperature  -   68.0 )   *   1.2 )   +
               ( percentHumidity  *   0.094 ));

   if   ( hi  >   79 )   {
    hi  =   - 42.379   +   2.04901523   *  temperature  +   10.14333127   *  percentHumidity  +
          - 0.22475541   *  temperature  *  percentHumidity  +
          - 0.00683783   *  pow ( temperature ,   2 )   +
          - 0.05481717   *  pow ( percentHumidity ,   2 )   +
          0.00122874   *  pow ( temperature ,   2 )   *  percentHumidity  +
          0.00085282   *  temperature  *  pow ( percentHumidity ,   2 )   +
          - 0.00000199   *  pow ( temperature ,   2 )   *  pow ( percentHumidity ,   2 );

     if   (( percentHumidity  <   13 )   &&   ( temperature  >=   80.0 )   &&
         ( temperature  <=   112.0 ))
      hi  -=   (( 13.0   -  percentHumidity )   *   0.25 )   *
            sqrt (( 17.0   -  abs ( temperature  -   95.0 ))   *   0.05882 );

     else   if   (( percentHumidity  >   85.0 )   &&   ( temperature  >=   80.0 )   &&
              ( temperature  <=   87.0 ))
      hi  +=   (( percentHumidity  -   85.0 )   *   0.1 )   *   (( 87.0   -  temperature )   *   0.2 );
   }

   return  isFahrenheit  ?  hi  :  convertFtoC ( hi );
}

/*!
 *  @brief  Read value from sensor or return last one from less than two
 *seconds.
 *  @param  force
 *          true if using force mode
 *  @return float value
 */
bool  DHT :: read ( bool  force )   {
   // Check if sensor was read less than two seconds ago and return early
   // to use last reading.
  uint32_t currenttime  =  millis ();
   if   ( ! force  &&   (( currenttime  -  _lastreadtime )   <  MIN_INTERVAL ))   {
     return  _lastresult ;   // return last correct measurement
   }
  _lastreadtime  =  currenttime ;

   // Reset 40 bits of received data to zero.
  data [ 0 ]   =  data [ 1 ]   =  data [ 2 ]   =  data [ 3 ]   =  data [ 4 ]   =   0 ;

#if  defined ( ESP8266 )
  yield ();   // Handle WiFi / reset software watchdog
#endif

   // Send start signal.  See DHT datasheet for full signal diagram:
   //   http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf

   // Go into high impedence state to let pull-up raise data line level and
   // start the reading process.
  pinMode ( _pin ,  INPUT_PULLUP );
  delay ( 1 );

   // First set data line low for a period according to sensor type
  pinMode ( _pin ,  OUTPUT );
  digitalWrite ( _pin ,  LOW );
   switch   ( _type )   {
   case  DHT22 :
   case  DHT21 :
    delayMicroseconds ( 1100 );   // data sheet says "at least 1ms"
     break ;
   case  DHT11 :
   default :
    delay ( 20 );   // data sheet says at least 18ms, 20ms just to be safe
     break ;
   }

  uint32_t cycles [ 80 ];
   {
     // End the start signal by setting data line high for 40 microseconds.
    pinMode ( _pin ,  INPUT_PULLUP );

     // Delay a moment to let sensor pull data line low.
    delayMicroseconds ( pullTime );

     // Now start reading the data line to get the value from the DHT sensor.

     // Turn off interrupts temporarily because the next sections
     // are timing critical and we don't want any interruptions.
     InterruptLock  lock ;

     // First expect a low signal for ~80 microseconds followed by a high signal
     // for ~80 microseconds again.
     if   ( expectPulse ( LOW )   ==  TIMEOUT )   {
      DEBUG_PRINTLN ( F ( "DHT timeout waiting for start signal low pulse." ));
      _lastresult  =   false ;
       return  _lastresult ;
     }
     if   ( expectPulse ( HIGH )   ==  TIMEOUT )   {
      DEBUG_PRINTLN ( F ( "DHT timeout waiting for start signal high pulse." ));
      _lastresult  =   false ;
       return  _lastresult ;
     }

     // Now read the 40 bits sent by the sensor.  Each bit is sent as a 50
     // microsecond low pulse followed by a variable length high pulse.  If the
     // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds
     // then it's a 1.  We measure the cycle count of the initial 50us low pulse
     // and use that to compare to the cycle count of the high pulse to determine
     // if the bit is a 0 (high state cycle count < low state cycle count), or a
     // 1 (high state cycle count > low state cycle count). Note that for speed
     // all the pulses are read into a array and then examined in a later step.
     for   ( int  i  =   0 ;  i  <   80 ;  i  +=   2 )   {
      cycles [ i ]   =  expectPulse ( LOW );
      cycles [ +   1 ]   =  expectPulse ( HIGH );
     }
   }   // Timing critical code is now complete.

   // Inspect pulses and determine which ones are 0 (high state cycle count < low
   // state cycle count), or 1 (high state cycle count > low state cycle count).
   for   ( int  i  =   0 ;  i  <   40 ;   ++ i )   {
    uint32_t lowCycles  =  cycles [ 2   *  i ];
    uint32_t highCycles  =  cycles [ 2   *  i  +   1 ];
     if   (( lowCycles  ==  TIMEOUT )   ||   ( highCycles  ==  TIMEOUT ))   {
      DEBUG_PRINTLN ( F ( "DHT timeout waiting for pulse." ));
      _lastresult  =   false ;
       return  _lastresult ;
     }
    data [ /   8 ]   <<=   1 ;
     // Now compare the low and high cycle times to see if the bit is a 0 or 1.
     if   ( highCycles  >  lowCycles )   {
       // High cycles are greater than 50us low cycle count, must be a 1.
      data [ /   8 ]   |=   1 ;
     }
     // Else high cycles are less than (or equal to, a weird case) the 50us low
     // cycle count so this must be a zero.  Nothing needs to be changed in the
     // stored data.
   }

  DEBUG_PRINTLN ( F ( "Received from DHT:" ));
  DEBUG_PRINT ( data [ 0 ],  HEX );
  DEBUG_PRINT ( F ( ", " ));
  DEBUG_PRINT ( data [ 1 ],  HEX );
  DEBUG_PRINT ( F ( ", " ));
  DEBUG_PRINT ( data [ 2 ],  HEX );
  DEBUG_PRINT ( F ( ", " ));
  DEBUG_PRINT ( data [ 3 ],  HEX );
  DEBUG_PRINT ( F ( ", " ));
  DEBUG_PRINT ( data [ 4 ],  HEX );
  DEBUG_PRINT ( F ( " =? " ));
  DEBUG_PRINTLN (( data [ 0 ]   +  data [ 1 ]   +  data [ 2 ]   +  data [ 3 ])   &   0xFF ,  HEX );

   // Check we read 40 bits and that the checksum matches.
   if   ( data [ 4 ]   ==   (( data [ 0 ]   +  data [ 1 ]   +  data [ 2 ]   +  data [ 3 ])   &   0xFF ))   {
    _lastresult  =   true ;
     return  _lastresult ;
   }   else   {
    DEBUG_PRINTLN ( F ( "DHT checksum failure!" ));
    _lastresult  =   false ;
     return  _lastresult ;
   }
}

// Expect the signal line to be at the specified level for a period of time and
// return a count of loop cycles spent at that level (this cycle count can be
// used to compare the relative time of two pulses).  If more than a millisecond
// ellapses without the level changing then the call fails with a 0 response.
// This is adapted from Arduino's pulseInLong function (which is only available
// in the very latest IDE versions):
//   https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_pulse.c
uint32_t DHT :: expectPulse ( bool  level )   {
#if   ( F_CPU  >   16000000L )
  uint32_t count  =   0 ;
#else
  uint16_t count  =   0 ;   // To work fast enough on slower AVR boards
#endif
// On AVR platforms use direct GPIO port access as it's much faster and better
// for catching pulses that are 10's of microseconds in length:
#ifdef  __AVR
  uint8_t portState  =  level  ?  _bit  :   0 ;
   while   (( * portInputRegister ( _port )   &  _bit )   ==  portState )   {
     if   ( count ++   >=  _maxcycles )   {
       return  TIMEOUT ;   // Exceeded timeout, fail.
     }
   }
// Otherwise fall back to using digitalRead (this seems to be necessary on
// ESP8266 right now, perhaps bugs in direct port access functions?).
#else
   while   ( digitalRead ( _pin )   ==  level )   {
     if   ( count ++   >=  _maxcycles )   {
       return  TIMEOUT ;   // Exceeded timeout, fail.
     }
   }
#endif

   return  count ;
}

SHS/Temperature_and_humidity/DHT.h

/*! * @file DHT.h * * This is a library for DHT series of low cost temperature/humidity sensors. * * You must have Adafruit Unified Sensor Library library installed to use this * class. * * Adafruit invests time and resources providing this open source code, * please support Adafruit andopen-source hardware by purchasing products * from Adafruit! * * Written by Adafruit Industries. * * MIT license, all text above must be included in any redistribution */ #ifndef DHT_H #define DHT_H #include "Arduino.h" /* Uncomment to enable printing out nice debug messages. */ //#define DHT_DEBUG #define DEBUG_PRINTER \ Serial /**< Define where debug output will be printed. \ */ /* Setup debug printing macros. */ #ifdef DHT_DEBUG #define DEBUG_PRINT(...) \ { DEBUG_PRINTER.print(__VA_ARGS__); } #define DEBUG_PRINTLN(...) \ { DEBUG_PRINTER.println(__VA_ARGS__); } #else #define DEBUG_PRINT(...) \ {} /**< Debug Print Placeholder if Debug is disabled */ #define DEBUG_PRINTLN(...) \ {} /**< Debug Print Line Placeholder if Debug is disabled */ #endif /* Define types of sensors. */ #define DHT11 11 /**< DHT TYPE 11 */ #define DHT12 12 /**< DHY TYPE 12 */ #define DHT22 22 /**< DHT TYPE 22 */ #define DHT21 21 /**< DHT TYPE 21 */ #define AM2301 21 /**< AM2301 */ #if defined(TARGET_NAME) && (TARGET_NAME == ARDUINO_NANO33BLE) #ifndef microsecondsToClockCycles /*! * As of 7 Sep 2020 the Arduino Nano 33 BLE boards do not have * microsecondsToClockCycles defined. */ #define microsecondsToClockCycles(a) ((a) * (SystemCoreClock / 1000000L)) #endif #endif /*! * @brief Class that stores state and functions for DHT */ class DHT { public: DHT(uint8_t pin, uint8_t type, uint8_t count = 6); void begin(uint8_t usec = 55); float readTemperature(bool S = false, bool force = false); float convertCtoF(float); float convertFtoC(float); float computeHeatIndex(bool isFahrenheit = true); float computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit = true); float readHumidity(bool force = false); bool read(bool force = false); private: uint8_t data[5]; uint8_t _pin, _type; #ifdef __AVR // Use direct GPIO access on an 8-bit AVR so keep track of the port and // bitmask for the digital pin connected to the DHT. Other platforms will use // digitalRead. uint8_t _bit, _port; #endif uint32_t _lastreadtime, _maxcycles; bool _lastresult; uint8_t pullTime; // Time (in usec) to pull up data line before reading uint32_t expectPulse(bool level); }; /*! * @brief Class that defines Interrupt Lock Avaiability */ class InterruptLock { public: InterruptLock() { #if !defined(ARDUINO_ARCH_NRF52) noInterrupts(); #endif } ~InterruptLock() { #if !defined(ARDUINO_ARCH_NRF52) interrupts(); #endif } }; #endif

SHS/Temperature_and_humidity/dht11.cpp

SHS/Temperature_and_humidity/dht11.cpp

//
//    FILE: dht11.cpp
// VERSION: 0.4.1
// PURPOSE: DHT11 Temperature & Humidity Sensor library for Arduino
// LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html)
//
// DATASHEET: http://www.micro4you.com/files/sensor/DHT11.pdf
//
// HISTORY:
// George Hadjikyriacou - Original version (??)
// Mod by SimKard - Version 0.2 (24/11/2010)
// Mod by Rob Tillaart - Version 0.3 (28/03/2011)
// + added comments
// + removed all non DHT11 specific code
// + added references
// Mod by Rob Tillaart - Version 0.4 (17/03/2012)
// + added 1.0 support
// Mod by Rob Tillaart - Version 0.4.1 (19/05/2012)
// + added error codes
//

#include   "dht11.h"

// Return values:
// DHTLIB_OK
// DHTLIB_ERROR_CHECKSUM
// DHTLIB_ERROR_TIMEOUT
int  dht11 :: read ( int  pin )
{
     // BUFFER TO RECEIVE
    uint8_t bits [ 5 ];
    uint8_t cnt  =   7 ;
    uint8_t idx  =   0 ;

     // EMPTY BUFFER
     for   ( int  i = 0 ;  i <   5 ;  i ++ )  bits [ i ]   =   0 ;

     // REQUEST SAMPLE
    pinMode ( pin ,  OUTPUT );
    digitalWrite ( pin ,  LOW );
    delay ( 18 );
    digitalWrite ( pin ,  HIGH );
    delayMicroseconds ( 40 );
    pinMode ( pin ,  INPUT );

     // ACKNOWLEDGE or TIMEOUT
     unsigned   int  loopCnt  =   10000 ;
     while ( digitalRead ( pin )   ==  LOW )
         if   ( loopCnt --   ==   0 )   return  DHTLIB_ERROR_TIMEOUT ;

    loopCnt  =   10000 ;
     while ( digitalRead ( pin )   ==  HIGH )
         if   ( loopCnt --   ==   0 )   return  DHTLIB_ERROR_TIMEOUT ;

     // READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT
     for   ( int  i = 0 ;  i < 40 ;  i ++ )
     {
        loopCnt  =   10000 ;
         while ( digitalRead ( pin )   ==  LOW )
             if   ( loopCnt --   ==   0 )   return  DHTLIB_ERROR_TIMEOUT ;

         unsigned   long  t  =  micros ();

        loopCnt  =   10000 ;
         while ( digitalRead ( pin )   ==  HIGH )
             if   ( loopCnt --   ==   0 )   return  DHTLIB_ERROR_TIMEOUT ;

         if   (( micros ()   -  t )   >   40 )  bits [ idx ]   |=   ( 1   <<  cnt );
         if   ( cnt  ==   0 )     // next byte?
         {
            cnt  =   7 ;      // restart at MSB
            idx ++ ;        // next byte!
         }
         else  cnt -- ;
     }

     // WRITE TO RIGHT VARS
         // as bits[1] and bits[3] are allways zero they are omitted in formulas.
    humidity     =  bits [ 0 ];
    temperature  =  bits [ 2 ];

    uint8_t sum  =  bits [ 0 ]   +  bits [ 2 ];

     if   ( bits [ 4 ]   !=  sum )   return  DHTLIB_ERROR_CHECKSUM ;
     return  DHTLIB_OK ;
}
//
// END OF FILE
//

SHS/Temperature_and_humidity/dht11.h

#ifndef dht11_h #define dht11_h #if defined(ARDUINO) && (ARDUINO >= 100) #include <Arduino.h> #else #include <WProgram.h> #endif #define DHT11LIB_VERSION "0.4.1" #define DHTLIB_OK 0 #define DHTLIB_ERROR_CHECKSUM -1 #define DHTLIB_ERROR_TIMEOUT -2 class dht11 { public: int read(int pin); int humidity; int temperature; }; #endif // // END OF FILE //

SHS/Temperature_and_humidity/DHT_U.cpp

SHS/Temperature_and_humidity/DHT_U.cpp

/*!
 *  @file DHT_U.cpp
 *
 *  Temperature & Humidity Unified Sensor Library
 *
 *  This is a library for DHT series of low cost temperature/humidity sensors.
 *
 *  You must have Adafruit Unified Sensor Library library installed to use this
 * class.
 *
 *  Adafruit invests time and resources providing this open source code,
 *  please support Adafruit andopen-source hardware by purchasing products
 *  from Adafruit!
 */
#include   "DHT_U.h"

/*!
 *  @brief  Instantiates a new DHT_Unified class
 *  @param  pin
 *          pin number that sensor is connected
 *  @param  type
 *          type of sensor
 *  @param  count
 *          number of sensors
 *  @param  tempSensorId
 *          temperature sensor id
 *  @param  humiditySensorId
 *          humidity sensor id
 */
DHT_Unified :: DHT_Unified ( uint8_t pin ,  uint8_t type ,  uint8_t count ,
                         int32_t tempSensorId ,  int32_t humiditySensorId )
     :  _dht ( pin ,  type ,  count ),  _type ( type ),  _temp ( this ,  tempSensorId ),
      _humidity ( this ,  humiditySensorId )   {}

/*!
 *  @brief  Setup sensor (calls begin on It)
 */
void   DHT_Unified :: begin ()   {  _dht . begin ();   }

/*!
 *  @brief  Sets sensor name
 *  @param  sensor
 *          Sensor that will be set
 */
void   DHT_Unified :: setName ( sensor_t  * sensor )   {
   switch   ( _type )   {
   case  DHT11 :
    strncpy ( sensor -> name ,   "DHT11" ,   sizeof ( sensor -> name )   -   1 );
     break ;
   case  DHT12 :
    strncpy ( sensor -> name ,   "DHT12" ,   sizeof ( sensor -> name )   -   1 );
     break ;
   case  DHT21 :
    strncpy ( sensor -> name ,   "DHT21" ,   sizeof ( sensor -> name )   -   1 );
     break ;
   case  DHT22 :
    strncpy ( sensor -> name ,   "DHT22" ,   sizeof ( sensor -> name )   -   1 );
     break ;
   default :
     // TODO: Perhaps this should be an error?  However main DHT library doesn't
     // enforce restrictions on the sensor type value.  Pick a generic name for
     // now.
    strncpy ( sensor -> name ,   "DHT?" ,   sizeof ( sensor -> name )   -   1 );
     break ;
   }
  sensor -> name [ sizeof ( sensor -> name )   -   1 ]   =   0 ;
}

/*!
 *  @brief  Sets Minimum Delay Value
 *  @param  sensor
 *          Sensor that will be set
 */
void   DHT_Unified :: setMinDelay ( sensor_t  * sensor )   {
   switch   ( _type )   {
   case  DHT11 :
    sensor -> min_delay  =   1000000L ;   // 1 second (in microseconds)
     break ;
   case  DHT12 :
    sensor -> min_delay  =   2000000L ;   // 2 second (in microseconds)
     break ;
   case  DHT21 :
    sensor -> min_delay  =   2000000L ;   // 2 seconds (in microseconds)
     break ;
   case  DHT22 :
    sensor -> min_delay  =   2000000L ;   // 2 seconds (in microseconds)
     break ;
   default :
     // Default to slowest sample rate in case of unknown type.
    sensor -> min_delay  =   2000000L ;   // 2 seconds (in microseconds)
     break ;
   }
}

/*!
 *  @brief  Instantiates a new DHT_Unified Temperature Class
 *  @param  parent
 *          Parent Sensor
 *  @param  id
 *          Sensor id
 */
DHT_Unified :: Temperature :: Temperature ( DHT_Unified   * parent ,  int32_t id )
     :  _parent ( parent ),  _id ( id )   {}

/*!
 *  @brief  Reads the sensor and returns the data as a sensors_event_t
 *  @param  event
 *  @return always returns true
 */
bool   DHT_Unified :: Temperature :: getEvent ( sensors_event_t  * event )   {
   // Clear event definition.
  memset ( event ,   0 ,   sizeof ( sensors_event_t ));
   // Populate sensor reading values.
   event -> version  =   sizeof ( sensors_event_t );
   event -> sensor_id  =  _id ;
   event -> type  =  SENSOR_TYPE_AMBIENT_TEMPERATURE ;
   event -> timestamp  =  millis ();
   event -> temperature  =  _parent -> _dht . readTemperature ();

   return   true ;
}

/*!
 *  @brief  Provides the sensor_t data for this sensor
 *  @param  sensor
 */
void   DHT_Unified :: Temperature :: getSensor ( sensor_t  * sensor )   {
   // Clear sensor definition.
  memset ( sensor ,   0 ,   sizeof ( sensor_t ));
   // Set sensor name.
  _parent -> setName ( sensor );
   // Set version and ID
  sensor -> version  =  DHT_SENSOR_VERSION ;
  sensor -> sensor_id  =  _id ;
   // Set type and characteristics.
  sensor -> type  =  SENSOR_TYPE_AMBIENT_TEMPERATURE ;
  _parent -> setMinDelay ( sensor );
   switch   ( _parent -> _type )   {
   case  DHT11 :
    sensor -> max_value  =   50.0F ;
    sensor -> min_value  =   0.0F ;
    sensor -> resolution  =   2.0F ;
     break ;
   case  DHT12 :
    sensor -> max_value  =   60.0F ;
    sensor -> min_value  =   - 20.0F ;
    sensor -> resolution  =   0.5F ;
     break ;
   case  DHT21 :
    sensor -> max_value  =   80.0F ;
    sensor -> min_value  =   - 40.0F ;
    sensor -> resolution  =   0.1F ;
     break ;
   case  DHT22 :
    sensor -> max_value  =   125.0F ;
    sensor -> min_value  =   - 40.0F ;
    sensor -> resolution  =   0.1F ;
     break ;
   default :
     // Unknown type, default to 0.
    sensor -> max_value  =   0.0F ;
    sensor -> min_value  =   0.0F ;
    sensor -> resolution  =   0.0F ;
     break ;
   }
}

/*!
 *  @brief  Instantiates a new DHT_Unified Humidity Class
 *  @param  parent
 *          Parent Sensor
 *  @param  id
 *          Sensor id
 */
DHT_Unified :: Humidity :: Humidity ( DHT_Unified   * parent ,  int32_t id )
     :  _parent ( parent ),  _id ( id )   {}

/*!
 *  @brief  Reads the sensor and returns the data as a sensors_event_t
 *  @param  event
 *  @return always returns true
 */
bool   DHT_Unified :: Humidity :: getEvent ( sensors_event_t  * event )   {
   // Clear event definition.
  memset ( event ,   0 ,   sizeof ( sensors_event_t ));
   // Populate sensor reading values.
   event -> version  =   sizeof ( sensors_event_t );
   event -> sensor_id  =  _id ;
   event -> type  =  SENSOR_TYPE_RELATIVE_HUMIDITY ;
   event -> timestamp  =  millis ();
   event -> relative_humidity  =  _parent -> _dht . readHumidity ();

   return   true ;
}

/*!
 *  @brief  Provides the sensor_t data for this sensor
 *  @param  sensor
 */
void   DHT_Unified :: Humidity :: getSensor ( sensor_t  * sensor )   {
   // Clear sensor definition.
  memset ( sensor ,   0 ,   sizeof ( sensor_t ));
   // Set sensor name.
  _parent -> setName ( sensor );
   // Set version and ID
  sensor -> version  =  DHT_SENSOR_VERSION ;
  sensor -> sensor_id  =  _id ;
   // Set type and characteristics.
  sensor -> type  =  SENSOR_TYPE_RELATIVE_HUMIDITY ;
  _parent -> setMinDelay ( sensor );
   switch   ( _parent -> _type )   {
   case  DHT11 :
    sensor -> max_value  =   80.0F ;
    sensor -> min_value  =   20.0F ;
    sensor -> resolution  =   5.0F ;
     break ;
   case  DHT12 :
    sensor -> max_value  =   95.0F ;
    sensor -> min_value  =   20.0F ;
    sensor -> resolution  =   5.0F ;
     break ;
   case  DHT21 :
    sensor -> max_value  =   100.0F ;
    sensor -> min_value  =   0.0F ;
    sensor -> resolution  =   0.1F ;
     break ;
   case  DHT22 :
    sensor -> max_value  =   100.0F ;
    sensor -> min_value  =   0.0F ;
    sensor -> resolution  =   0.1F ;
     break ;
   default :
     // Unknown type, default to 0.
    sensor -> max_value  =   0.0F ;
    sensor -> min_value  =   0.0F ;
    sensor -> resolution  =   0.0F ;
     break ;
   }
}

SHS/Temperature_and_humidity/DHT_U.h

/*! * @file DHT_U.h * * DHT Temperature & Humidity Unified Sensor Library<Paste> * * Adafruit invests time and resources providing this open source code, * please support Adafruit andopen-source hardware by purchasing products * from Adafruit! * * Written by Tony DiCola (Adafruit Industries) 2014. * * MIT license, all text above must be included in any redistribution * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef DHT_U_H #define DHT_U_H #include "Adafruit_Sensor.h" #include "DHT.h" #define DHT_SENSOR_VERSION 1 /**< Sensor Version */ /*! * @brief Class that stores state and functions for interacting with * DHT_Unified. */ class DHT_Unified { public: DHT_Unified(uint8_t pin, uint8_t type, uint8_t count = 6, int32_t tempSensorId = -1, int32_t humiditySensorId = -1); void begin(); /*! * @brief Class that stores state and functions about Temperature */ class Temperature : public Adafruit_Sensor { public: Temperature(DHT_Unified *parent, int32_t id); bool getEvent(sensors_event_t *event); void getSensor(sensor_t *sensor); private: DHT_Unified *_parent; int32_t _id; }; /*! * @brief Class that stores state and functions about Humidity */ class Humidity : public Adafruit_Sensor { public: Humidity(DHT_Unified *parent, int32_t id); bool getEvent(sensors_event_t *event); void getSensor(sensor_t *sensor); private: DHT_Unified *_parent; int32_t _id; }; /*! * @brief Returns temperature stored in _temp * @return Temperature value */ Temperature temperature() { return _temp; } /*! * @brief Returns humidity stored in _humidity * @return Humidity value */ Humidity humidity() { return _humidity; } private: DHT _dht; uint8_t _type; Temperature _temp; Humidity _humidity; void setName(sensor_t *sensor); void setMinDelay(sensor_t *sensor); }; #endif

SHS/Temperature_and_humidity/LiquidCrystal_I2C.cpp

SHS/Temperature_and_humidity/LiquidCrystal_I2C.cpp

/**********************************************
LiquidCrystal_I2C
last updated on 21/12/2011
Tim Starling Fix the reset bug (Thanks Tim)
www.yfrobot.com
**********************************************/


#include   "LiquidCrystal_I2C.h"
#include   < inttypes . h >
#if  defined ( ARDUINO )   &&  ARDUINO  >=   100

#include   "Arduino.h"

#define  printIIC ( args )    Wire . write ( args )
inline  size_t  LiquidCrystal_I2C :: write ( uint8_t  value )   {
    send ( value ,   Rs );
     return   1 ;
}

#else
#include   "WProgram.h"

#define  printIIC ( args )    Wire . send ( args )
inline   void   LiquidCrystal_I2C :: write ( uint8_t  value )   {
    send ( value ,   Rs );
}

#endif
#include   "Wire.h"



// When the display powers up, it is configured as follows:
//
// 1. Display clear
// 2. Function set: 
//    DL = 1; 8-bit interface data 
//    N = 0; 1-line display 
//    F = 0; 5x8 dot character font 
// 3. Display on/off control: 
//    D = 0; Display off 
//    C = 0; Cursor off 
//    B = 0; Blinking off 
// 4. Entry mode set: 
//    I/D = 1; Increment by 1
//    S = 0; No shift 
//
// Note, however, that resetting the Arduino doesn't reset the LCD, so we
// can't assume that its in that state when a sketch starts (and the
// LiquidCrystal constructor is called).

LiquidCrystal_I2C :: LiquidCrystal_I2C ( uint8_t lcd_Addr , uint8_t lcd_cols , uint8_t lcd_rows )
{
  _Addr  =  lcd_Addr ;
  _cols  =  lcd_cols ;
  _rows  =  lcd_rows ;
  _backlightval  =  LCD_NOBACKLIGHT ;
}

void   LiquidCrystal_I2C :: init (){
    init_priv ();
}

void   LiquidCrystal_I2C :: init_priv ()
{
     Wire . begin ();
    _displayfunction  =  LCD_4BITMODE  |  LCD_1LINE  |   LCD_5x8DOTS ;
    begin ( _cols ,  _rows );   
}

void   LiquidCrystal_I2C :: begin ( uint8_t cols ,  uint8_t lines ,  uint8_t dotsize )   {
     if   ( lines  >   1 )   {
        _displayfunction  |=  LCD_2LINE ;
     }
    _numlines  =  lines ;

     // for some 1 line displays you can select a 10 pixel high font
     if   (( dotsize  !=   0 )   &&   ( lines  ==   1 ))   {
        _displayfunction  |=   LCD_5x10DOTS ;
     }

     // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
     // according to datasheet, we need at least 40ms after power rises above 2.7V
     // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
    delay ( 50 );  
  
     // Now we pull both RS and R/W low to begin commands
    expanderWrite ( _backlightval );     // reset expanderand turn backlight off (Bit 8 =1)
    delay ( 1000 );

     //put the LCD into 4 bit mode
     // this is according to the hitachi HD44780 datasheet
     // figure 24, pg 46
    
       // we start in 8bit mode, try to set 4 bit mode
   write4bits ( 0x03   <<   4 );
   delayMicroseconds ( 4100 );   // wait min 4.1ms
   
    // second try
   write4bits ( 0x03   <<   4 );
   delayMicroseconds ( 4100 );   // wait min 4.1ms
   
    // third go!
   write4bits ( 0x03   <<   4 );  
   delayMicroseconds ( 150 );
   
    // finally, set to 4-bit interface
   write4bits ( 0x02   <<   4 );  


     // set # lines, font size, etc.
    command ( LCD_FUNCTIONSET  |  _displayfunction );   
    
     // turn the display on with no cursor or blinking default
    _displaycontrol  =  LCD_DISPLAYON  |  LCD_CURSOROFF  |  LCD_BLINKOFF ;
    display ();
    
     // clear it off
    clear ();
    
     // Initialize to default text direction (for roman languages)
    _displaymode  =  LCD_ENTRYLEFT  |  LCD_ENTRYSHIFTDECREMENT ;
    
     // set the entry mode
    command ( LCD_ENTRYMODESET  |  _displaymode );
    
    home ();
  
}

/********** high level commands, for the user! */
void   LiquidCrystal_I2C :: clear (){
    command ( LCD_CLEARDISPLAY ); // clear display, set cursor position to zero
    delayMicroseconds ( 2000 );    // this command takes a long time!
}

void   LiquidCrystal_I2C :: home (){
    command ( LCD_RETURNHOME );    // set cursor position to zero
    delayMicroseconds ( 2000 );    // this command takes a long time!
}

void   LiquidCrystal_I2C :: setCursor ( uint8_t col ,  uint8_t row ){
     int  row_offsets []   =   {   0x00 ,   0x40 ,   0x14 ,   0x54   };
     if   (  row  >  _numlines  )   {
        row  =  _numlines - 1 ;      // we count rows starting w/0
     }
    command ( LCD_SETDDRAMADDR  |   ( col  +  row_offsets [ row ]));
}

// Turn the display on/off (quickly)
void   LiquidCrystal_I2C :: noDisplay ()   {
    _displaycontrol  &=   ~ LCD_DISPLAYON ;
    command ( LCD_DISPLAYCONTROL  |  _displaycontrol );
}
void   LiquidCrystal_I2C :: display ()   {
    _displaycontrol  |=  LCD_DISPLAYON ;
    command ( LCD_DISPLAYCONTROL  |  _displaycontrol );
}

// Turns the underline cursor on/off
void   LiquidCrystal_I2C :: noCursor ()   {
    _displaycontrol  &=   ~ LCD_CURSORON ;
    command ( LCD_DISPLAYCONTROL  |  _displaycontrol );
}
void   LiquidCrystal_I2C :: cursor ()   {
    _displaycontrol  |=  LCD_CURSORON ;
    command ( LCD_DISPLAYCONTROL  |  _displaycontrol );
}

// Turn on and off the blinking cursor
void   LiquidCrystal_I2C :: noBlink ()   {
    _displaycontrol  &=   ~ LCD_BLINKON ;
    command ( LCD_DISPLAYCONTROL  |  _displaycontrol );
}
void   LiquidCrystal_I2C :: blink ()   {
    _displaycontrol  |=  LCD_BLINKON ;
    command ( LCD_DISPLAYCONTROL  |  _displaycontrol );
}

// These commands scroll the display without changing the RAM
void   LiquidCrystal_I2C :: scrollDisplayLeft ( void )   {
    command ( LCD_CURSORSHIFT  |  LCD_DISPLAYMOVE  |  LCD_MOVELEFT );
}
void   LiquidCrystal_I2C :: scrollDisplayRight ( void )   {
    command ( LCD_CURSORSHIFT  |  LCD_DISPLAYMOVE  |  LCD_MOVERIGHT );
}

// This is for text that flows Left to Right
void   LiquidCrystal_I2C :: leftToRight ( void )   {
    _displaymode  |=  LCD_ENTRYLEFT ;
    command ( LCD_ENTRYMODESET  |  _displaymode );
}

// This is for text that flows Right to Left
void   LiquidCrystal_I2C :: rightToLeft ( void )   {
    _displaymode  &=   ~ LCD_ENTRYLEFT ;
    command ( LCD_ENTRYMODESET  |  _displaymode );
}

// This will 'right justify' text from the cursor
void   LiquidCrystal_I2C :: autoscroll ( void )   {
    _displaymode  |=  LCD_ENTRYSHIFTINCREMENT ;
    command ( LCD_ENTRYMODESET  |  _displaymode );
}

// This will 'left justify' text from the cursor
void   LiquidCrystal_I2C :: noAutoscroll ( void )   {
    _displaymode  &=   ~ LCD_ENTRYSHIFTINCREMENT ;
    command ( LCD_ENTRYMODESET  |  _displaymode );
}

// Allows us to fill the first 8 CGRAM locations
// with custom characters
void   LiquidCrystal_I2C :: createChar ( uint8_t location ,  uint8_t charmap [])   {
    location  &=   0x7 ;   // we only have 8 locations 0-7
    command ( LCD_SETCGRAMADDR  |   ( location  <<   3 ));
     for   ( int  i = 0 ;  i < 8 ;  i ++ )   {
        write ( charmap [ i ]);
     }
}

// Turn the (optional) backlight off/on
void   LiquidCrystal_I2C :: noBacklight ( void )   {
    _backlightval = LCD_NOBACKLIGHT ;
    expanderWrite ( 0 );
}

void   LiquidCrystal_I2C :: backlight ( void )   {
    _backlightval = LCD_BACKLIGHT ;
    expanderWrite ( 0 );
}



/*********** mid level commands, for sending data/cmds */

inline   void   LiquidCrystal_I2C :: command ( uint8_t  value )   {
    send ( value ,   0 );
}


/************ low level data pushing commands **********/

// write either command or data
void   LiquidCrystal_I2C :: send ( uint8_t  value ,  uint8_t mode )   {
    uint8_t highnib = value & 0xf0 ;
    uint8_t lownib = ( value << 4 ) & 0xf0 ;
       write4bits (( highnib ) | mode );
    write4bits (( lownib ) | mode );  
}

void   LiquidCrystal_I2C :: write4bits ( uint8_t  value )   {
    expanderWrite ( value );
    pulseEnable ( value );
}

void   LiquidCrystal_I2C :: expanderWrite ( uint8_t _data ){                                         
     Wire . beginTransmission ( _Addr );
    printIIC (( int )( _data )   |  _backlightval );
     Wire . endTransmission ();    
}

void   LiquidCrystal_I2C :: pulseEnable ( uint8_t _data ){
    expanderWrite ( _data  |   En );    // En high
    delayMicroseconds ( 1 );         // enable pulse must be >450ns
    
    expanderWrite ( _data  &   ~ En );   // En low
    delayMicroseconds ( 50 );        // commands need > 37us to settle
}  


// Alias functions

void   LiquidCrystal_I2C :: cursor_on (){
    cursor ();
}

void   LiquidCrystal_I2C :: cursor_off (){
    noCursor ();
}

void   LiquidCrystal_I2C :: blink_on (){
    blink ();
}

void   LiquidCrystal_I2C :: blink_off (){
    noBlink ();
}

void   LiquidCrystal_I2C :: load_custom_character ( uint8_t char_num ,  uint8_t  * rows ){
        createChar ( char_num ,  rows );
}

void   LiquidCrystal_I2C :: setBacklight ( uint8_t new_val ){
     if ( new_val ){
        backlight ();          // turn backlight on
     } else {
        noBacklight ();        // turn backlight off
     }
}

void   LiquidCrystal_I2C :: printstr ( const   char  c []){
     //This function is not identical to the function used for "real" I2C displays
     //it's here so the user sketch doesn't have to be changed 
    print ( c );
}


// unsupported API functions
void   LiquidCrystal_I2C :: off (){}
void   LiquidCrystal_I2C :: on (){}
void   LiquidCrystal_I2C :: setDelay  ( int  cmdDelay , int  charDelay )   {}
uint8_t  LiquidCrystal_I2C :: status (){ return   0 ;}
uint8_t  LiquidCrystal_I2C :: keypad  (){ return   0 ;}
uint8_t  LiquidCrystal_I2C :: init_bargraph ( uint8_t graphtype ){ return   0 ;}
void   LiquidCrystal_I2C :: draw_horizontal_graph ( uint8_t row ,  uint8_t column ,  uint8_t len ,   uint8_t pixel_col_end ){}
void   LiquidCrystal_I2C :: draw_vertical_graph ( uint8_t row ,  uint8_t column ,  uint8_t len ,   uint8_t pixel_row_end ){}
void   LiquidCrystal_I2C :: setContrast ( uint8_t new_val ){}

    

SHS/Temperature_and_humidity/LiquidCrystal_I2C.h

/********************************************** LiquidCrystal_I2C last updated on 21/12/2011 Tim Starling Fix the reset bug (Thanks Tim) www.yfrobot.com **********************************************/ #ifndef LiquidCrystal_I2C_h #define LiquidCrystal_I2C_h #include <inttypes.h> #include "Print.h" #include <Wire.h> // commands #define LCD_CLEARDISPLAY 0x01 #define LCD_RETURNHOME 0x02 #define LCD_ENTRYMODESET 0x04 #define LCD_DISPLAYCONTROL 0x08 #define LCD_CURSORSHIFT 0x10 #define LCD_FUNCTIONSET 0x20 #define LCD_SETCGRAMADDR 0x40 #define LCD_SETDDRAMADDR 0x80 // flags for display entry mode #define LCD_ENTRYRIGHT 0x00 #define LCD_ENTRYLEFT 0x02 #define LCD_ENTRYSHIFTINCREMENT 0x01 #define LCD_ENTRYSHIFTDECREMENT 0x00 // flags for display on/off control #define LCD_DISPLAYON 0x04 #define LCD_DISPLAYOFF 0x00 #define LCD_CURSORON 0x02 #define LCD_CURSOROFF 0x00 #define LCD_BLINKON 0x01 #define LCD_BLINKOFF 0x00 // flags for display/cursor shift #define LCD_DISPLAYMOVE 0x08 #define LCD_CURSORMOVE 0x00 #define LCD_MOVERIGHT 0x04 #define LCD_MOVELEFT 0x00 // flags for function set #define LCD_8BITMODE 0x10 #define LCD_4BITMODE 0x00 #define LCD_2LINE 0x08 #define LCD_1LINE 0x00 #define LCD_5x10DOTS 0x04 #define LCD_5x8DOTS 0x00 // flags for backlight control #define LCD_BACKLIGHT 0x08 #define LCD_NOBACKLIGHT 0x00 #define En B00000100 // Enable bit #define Rw B00000010 // Read/Write bit #define Rs B00000001 // Register select bit class LiquidCrystal_I2C : public Print { public: LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows); void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS ); void clear(); void home(); void noDisplay(); void display(); void noBlink(); void blink(); void noCursor(); void cursor(); void scrollDisplayLeft(); void scrollDisplayRight(); void printLeft(); void printRight(); void leftToRight(); void rightToLeft(); void shiftIncrement(); void shiftDecrement(); void noBacklight(); void backlight(); void autoscroll(); void noAutoscroll(); void createChar(uint8_t, uint8_t[]); void setCursor(uint8_t, uint8_t); #if defined(ARDUINO) && ARDUINO >= 100 virtual size_t write(uint8_t); #else virtual void write(uint8_t); #endif void command(uint8_t); void init(); ////compatibility API function aliases void blink_on(); // alias for blink() void blink_off(); // alias for noBlink() void cursor_on(); // alias for cursor() void cursor_off(); // alias for noCursor() void setBacklight(uint8_t new_val); // alias for backlight() and nobacklight() void load_custom_character(uint8_t char_num, uint8_t *rows); // alias for createChar() void printstr(const char[]); ////Unsupported API functions (not implemented in this library) uint8_t status(); void setContrast(uint8_t new_val); uint8_t keypad(); void setDelay(int,int); void on(); void off(); uint8_t init_bargraph(uint8_t graphtype); void draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end); void draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end); private: void init_priv(); void send(uint8_t, uint8_t); void write4bits(uint8_t); void expanderWrite(uint8_t); void pulseEnable(uint8_t); uint8_t _Addr; uint8_t _displayfunction; uint8_t _displaycontrol; uint8_t _displaymode; uint8_t _numlines; uint8_t _cols; uint8_t _rows; uint8_t _backlightval; }; #endif

SHS/Temperature_and_humidity/LiquidCrystal_SoftI2C.cpp

SHS/Temperature_and_humidity/LiquidCrystal_SoftI2C.cpp

// Based on the work by DFRobot

#include   "LiquidCrystal_SoftI2C.h"
#include   < inttypes . h >
#if  defined ( ARDUINO )   &&  ARDUINO  >=   100

#include   "Arduino.h"

#define  printIIC ( args )   i2c . write ( args )
inline  size_t  LiquidCrystal_SoftI2C :: write ( uint8_t  value )   {
    send ( value ,   Rs );
     return   1 ;
}

#else
#include   "WProgram.h"

#define  printIIC ( args )   i2c . send ( args )
inline   void   LiquidCrystal_SoftI2C :: write ( uint8_t  value )   {
    send ( value ,   Rs );
}

#endif




// When the display powers up, it is configured as follows:
//
// 1. Display clear
// 2. Function set: 
//    DL = 1; 8-bit interface data 
//    N = 0; 1-line display 
//    F = 0; 5x8 dot character font 
// 3. Display on/off control: 
//    D = 0; Display off 
//    C = 0; Cursor off 
//    B = 0; Blinking off 
// 4. Entry mode set: 
//    I/D = 1; Increment by 1
//    S = 0; No shift 
//
// Note, however, that resetting the Arduino doesn't reset the LCD, so we
// can't assume that its in that state when a sketch starts (and the
// LiquidCrystal constructor is called).

LiquidCrystal_SoftI2C :: LiquidCrystal_SoftI2C ( uint8_t lcd_Addr , uint8_t lcd_cols , uint8_t lcd_rows ,  uint8_t sclPin ,  uint8_t sdaPin )
{
  _Addr  =  lcd_Addr ;
  _cols  =  lcd_cols ;
  _rows  =  lcd_rows ;
  _backlightval  =  LCD_NOBACKLIGHT ;
  i2c  =    SoftI2CMaster ( sclPin ,  sdaPin ,   0 );
}

void   LiquidCrystal_SoftI2C :: init (){
    init_priv ();
}

void   LiquidCrystal_SoftI2C :: init_priv ()
{
    i2c . begin ();
    _displayfunction  =  LCD_4BITMODE  |  LCD_1LINE  |   LCD_5x8DOTS ;
    begin ( _cols ,  _rows );   
}

void   LiquidCrystal_SoftI2C :: begin ( uint8_t cols ,  uint8_t lines ,  uint8_t dotsize )   {
     if   ( lines  >   1 )   {
        _displayfunction  |=  LCD_2LINE ;
     }
    _numlines  =  lines ;

     // for some 1 line displays you can select a 10 pixel high font
     if   (( dotsize  !=   0 )   &&   ( lines  ==   1 ))   {
        _displayfunction  |=   LCD_5x10DOTS ;
     }

     // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
     // according to datasheet, we need at least 40ms after power rises above 2.7V
     // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
    delay ( 50 );  
  
     // Now we pull both RS and R/W low to begin commands
    expanderWrite ( _backlightval );     // reset expanderand turn backlight off (Bit 8 =1)
    delay ( 1000 );

     //put the LCD into 4 bit mode
     // this is according to the hitachi HD44780 datasheet
     // figure 24, pg 46
    
       // we start in 8bit mode, try to set 4 bit mode
   write4bits ( 0x03   <<   4 );
   delayMicroseconds ( 4500 );   // wait min 4.1ms
   
    // second try
   write4bits ( 0x03   <<   4 );
   delayMicroseconds ( 4500 );   // wait min 4.1ms
   
    // third go!
   write4bits ( 0x03   <<   4 );  
   delayMicroseconds ( 150 );
   
    // finally, set to 4-bit interface
   write4bits ( 0x02   <<   4 );  


     // set # lines, font size, etc.
    command ( LCD_FUNCTIONSET  |  _displayfunction );   
    
     // turn the display on with no cursor or blinking default
    _displaycontrol  =  LCD_DISPLAYON  |  LCD_CURSOROFF  |  LCD_BLINKOFF ;
    display ();
    
     // clear it off
    clear ();
    
     // Initialize to default text direction (for roman languages)
    _displaymode  =  LCD_ENTRYLEFT  |  LCD_ENTRYSHIFTDECREMENT ;
    
     // set the entry mode
    command ( LCD_ENTRYMODESET  |  _displaymode );
    
    home ();
  
}

/********** high level commands, for the user! */
void   LiquidCrystal_SoftI2C :: clear (){
    command ( LCD_CLEARDISPLAY ); // clear display, set cursor position to zero
    delayMicroseconds ( 2000 );    // this command takes a long time!
}

void   LiquidCrystal_SoftI2C :: home (){
    command ( LCD_RETURNHOME );    // set cursor position to zero
    delayMicroseconds ( 2000 );    // this command takes a long time!
}

void   LiquidCrystal_SoftI2C :: setCursor ( uint8_t col ,  uint8_t row ){
     int  row_offsets []   =   {   0x00 ,   0x40 ,   0x14 ,   0x54   };
     if   (  row  >  _numlines  )   {
        row  =  _numlines - 1 ;      // we count rows starting w/0
     }
    command ( LCD_SETDDRAMADDR  |   ( col  +  row_offsets [ row ]));
}

// Turn the display on/off (quickly)
void   LiquidCrystal_SoftI2C :: noDisplay ()   {
    _displaycontrol  &=   ~ LCD_DISPLAYON ;
    command ( LCD_DISPLAYCONTROL  |  _displaycontrol );
}
void   LiquidCrystal_SoftI2C :: display ()   {
    _displaycontrol  |=  LCD_DISPLAYON ;
    command ( LCD_DISPLAYCONTROL  |  _displaycontrol );
}

// Turns the underline cursor on/off
void   LiquidCrystal_SoftI2C :: noCursor ()   {
    _displaycontrol  &=   ~ LCD_CURSORON ;
    command ( LCD_DISPLAYCONTROL  |  _displaycontrol );
}
void   LiquidCrystal_SoftI2C :: cursor ()   {
    _displaycontrol  |=  LCD_CURSORON ;
    command ( LCD_DISPLAYCONTROL  |  _displaycontrol );
}

// Turn on and off the blinking cursor
void   LiquidCrystal_SoftI2C :: noBlink ()   {
    _displaycontrol  &=   ~ LCD_BLINKON ;
    command ( LCD_DISPLAYCONTROL  |  _displaycontrol );
}
void   LiquidCrystal_SoftI2C :: blink ()   {
    _displaycontrol  |=  LCD_BLINKON ;
    command ( LCD_DISPLAYCONTROL  |  _displaycontrol );
}

// These commands scroll the display without changing the RAM
void   LiquidCrystal_SoftI2C :: scrollDisplayLeft ( void )   {
    command ( LCD_CURSORSHIFT  |  LCD_DISPLAYMOVE  |  LCD_MOVELEFT );
}
void   LiquidCrystal_SoftI2C :: scrollDisplayRight ( void )   {
    command ( LCD_CURSORSHIFT  |  LCD_DISPLAYMOVE  |  LCD_MOVERIGHT );
}

// This is for text that flows Left to Right
void   LiquidCrystal_SoftI2C :: leftToRight ( void )   {
    _displaymode  |=  LCD_ENTRYLEFT ;
    command ( LCD_ENTRYMODESET  |  _displaymode );
}

// This is for text that flows Right to Left
void   LiquidCrystal_SoftI2C :: rightToLeft ( void )   {
    _displaymode  &=   ~ LCD_ENTRYLEFT ;
    command ( LCD_ENTRYMODESET  |  _displaymode );
}

// This will 'right justify' text from the cursor
void   LiquidCrystal_SoftI2C :: autoscroll ( void )   {
    _displaymode  |=  LCD_ENTRYSHIFTINCREMENT ;
    command ( LCD_ENTRYMODESET  |  _displaymode );
}

// This will 'left justify' text from the cursor
void   LiquidCrystal_SoftI2C :: noAutoscroll ( void )   {
    _displaymode  &=   ~ LCD_ENTRYSHIFTINCREMENT ;
    command ( LCD_ENTRYMODESET  |  _displaymode );
}

// Allows us to fill the first 8 CGRAM locations
// with custom characters
void   LiquidCrystal_SoftI2C :: createChar ( uint8_t location ,  uint8_t charmap [])   {
    location  &=   0x7 ;   // we only have 8 locations 0-7
    command ( LCD_SETCGRAMADDR  |   ( location  <<   3 ));
     for   ( int  i = 0 ;  i < 8 ;  i ++ )   {
        write ( charmap [ i ]);
     }
}

//createChar with PROGMEM input
void   LiquidCrystal_SoftI2C :: createChar ( uint8_t location ,   const   char   * charmap )   {
    location  &=   0x7 ;   // we only have 8 locations 0-7
    command ( LCD_SETCGRAMADDR  |   ( location  <<   3 ));
     for   ( int  i = 0 ;  i < 8 ;  i ++ )   {
            write ( pgm_read_byte_near ( charmap ++ ));
     }
}

// Turn the (optional) backlight off/on
void   LiquidCrystal_SoftI2C :: noBacklight ( void )   {
    _backlightval = LCD_NOBACKLIGHT ;
    expanderWrite ( 0 );
}

void   LiquidCrystal_SoftI2C :: backlight ( void )   {
    _backlightval = LCD_BACKLIGHT ;
    expanderWrite ( 0 );
}



/*********** mid level commands, for sending data/cmds */

inline   void   LiquidCrystal_SoftI2C :: command ( uint8_t  value )   {
    send ( value ,   0 );
}


/************ low level data pushing commands **********/

// write either command or data
void   LiquidCrystal_SoftI2C :: send ( uint8_t  value ,  uint8_t mode )   {
    uint8_t highnib = value & 0xf0 ;
    uint8_t lownib = ( value << 4 ) & 0xf0 ;
       write4bits (( highnib ) | mode );
    write4bits (( lownib ) | mode );  
}

void   LiquidCrystal_SoftI2C :: write4bits ( uint8_t  value )   {
    expanderWrite ( value );
    pulseEnable ( value );
}

void   LiquidCrystal_SoftI2C :: expanderWrite ( uint8_t _data ){                                         
    i2c . beginTransmission ( _Addr );
    printIIC (( int )( _data )   |  _backlightval );
    i2c . endTransmission ();    
}

void   LiquidCrystal_SoftI2C :: pulseEnable ( uint8_t _data ){
    expanderWrite ( _data  |   En );    // En high
    delayMicroseconds ( 1 );         // enable pulse must be >450ns
    
    expanderWrite ( _data  &   ~ En );   // En low
    delayMicroseconds ( 50 );        // commands need > 37us to settle
}  


// Alias functions

void   LiquidCrystal_SoftI2C :: cursor_on (){
    cursor ();
}

void   LiquidCrystal_SoftI2C :: cursor_off (){
    noCursor ();
}

void   LiquidCrystal_SoftI2C :: blink_on (){
    blink ();
}

void   LiquidCrystal_SoftI2C :: blink_off (){
    noBlink ();
}

void   LiquidCrystal_SoftI2C :: load_custom_character ( uint8_t char_num ,  uint8_t  * rows ){
        createChar ( char_num ,  rows );
}

void   LiquidCrystal_SoftI2C :: setBacklight ( uint8_t new_val ){
     if ( new_val ){
        backlight ();          // turn backlight on
     } else {
        noBacklight ();        // turn backlight off
     }
}

void   LiquidCrystal_SoftI2C :: printstr ( const   char  c []){
     //This function is not identical to the function used for "real" I2C displays
     //it's here so the user sketch doesn't have to be changed 
    print ( c );
}


// unsupported API functions
void   LiquidCrystal_SoftI2C :: off (){}
void   LiquidCrystal_SoftI2C :: on (){}
void   LiquidCrystal_SoftI2C :: setDelay  ( int  cmdDelay , int  charDelay )   {}
uint8_t  LiquidCrystal_SoftI2C :: status (){ return   0 ;}
uint8_t  LiquidCrystal_SoftI2C :: keypad  (){ return   0 ;}
uint8_t  LiquidCrystal_SoftI2C :: init_bargraph ( uint8_t graphtype ){ return   0 ;}
void   LiquidCrystal_SoftI2C :: draw_horizontal_graph ( uint8_t row ,  uint8_t column ,  uint8_t len ,   uint8_t pixel_col_end ){}
void   LiquidCrystal_SoftI2C :: draw_vertical_graph ( uint8_t row ,  uint8_t column ,  uint8_t len ,   uint8_t pixel_row_end ){}
void   LiquidCrystal_SoftI2C :: setContrast ( uint8_t new_val ){}

    

SHS/Temperature_and_humidity/LiquidCrystal_SoftI2C.h

//Mixly Team Edit #ifndef LiquidCrystal_SoftI2C_h #define LiquidCrystal_SoftI2C_h #include <inttypes.h> #include "Print.h" #include "SoftI2CMaster.h" // commands #define LCD_CLEARDISPLAY 0x01 #define LCD_RETURNHOME 0x02 #define LCD_ENTRYMODESET 0x04 #define LCD_DISPLAYCONTROL 0x08 #define LCD_CURSORSHIFT 0x10 #define LCD_FUNCTIONSET 0x20 #define LCD_SETCGRAMADDR 0x40 #define LCD_SETDDRAMADDR 0x80 // flags for display entry mode #define LCD_ENTRYRIGHT 0x00 #define LCD_ENTRYLEFT 0x02 #define LCD_ENTRYSHIFTINCREMENT 0x01 #define LCD_ENTRYSHIFTDECREMENT 0x00 // flags for display on/off control #define LCD_DISPLAYON 0x04 #define LCD_DISPLAYOFF 0x00 #define LCD_CURSORON 0x02 #define LCD_CURSOROFF 0x00 #define LCD_BLINKON 0x01 #define LCD_BLINKOFF 0x00 // flags for display/cursor shift #define LCD_DISPLAYMOVE 0x08 #define LCD_CURSORMOVE 0x00 #define LCD_MOVERIGHT 0x04 #define LCD_MOVELEFT 0x00 // flags for function set #define LCD_8BITMODE 0x10 #define LCD_4BITMODE 0x00 #define LCD_2LINE 0x08 #define LCD_1LINE 0x00 #define LCD_5x10DOTS 0x04 #define LCD_5x8DOTS 0x00 // flags for backlight control #define LCD_BACKLIGHT 0x08 #define LCD_NOBACKLIGHT 0x00 #define En B00000100 // Enable bit #define Rw B00000010 // Read/Write bit #define Rs B00000001 // Register select bit class LiquidCrystal_SoftI2C : public Print { public: LiquidCrystal_SoftI2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows, uint8_t sclPin, uint8_t sdaPin); void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS ); void clear(); void home(); void noDisplay(); void display(); void noBlink(); void blink(); void noCursor(); void cursor(); void scrollDisplayLeft(); void scrollDisplayRight(); void printLeft(); void printRight(); void leftToRight(); void rightToLeft(); void shiftIncrement(); void shiftDecrement(); void noBacklight(); void backlight(); void autoscroll(); void noAutoscroll(); void createChar(uint8_t, uint8_t[]); void createChar(uint8_t location, const char *charmap); // Example: const char bell[8] PROGMEM = {B00100,B01110,B01110,B01110,B11111,B00000,B00100,B00000}; void setCursor(uint8_t, uint8_t); #if defined(ARDUINO) && ARDUINO >= 100 virtual size_t write(uint8_t); #else virtual void write(uint8_t); #endif void command(uint8_t); void init(); ////compatibility API function aliases void blink_on(); // alias for blink() void blink_off(); // alias for noBlink() void cursor_on(); // alias for cursor() void cursor_off(); // alias for noCursor() void setBacklight(uint8_t new_val); // alias for backlight() and nobacklight() void load_custom_character(uint8_t char_num, uint8_t *rows); // alias for createChar() void printstr(const char[]); ////Unsupported API functions (not implemented in this library) uint8_t status(); void setContrast(uint8_t new_val); uint8_t keypad(); void setDelay(int,int); void on(); void off(); uint8_t init_bargraph(uint8_t graphtype); void draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end); void draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end); private: void init_priv(); void send(uint8_t, uint8_t); void write4bits(uint8_t); void expanderWrite(uint8_t); void pulseEnable(uint8_t); uint8_t _Addr; uint8_t _displayfunction; uint8_t _displaycontrol; uint8_t _displaymode; uint8_t _numlines; uint8_t _cols; uint8_t _rows; uint8_t _backlightval; SoftI2CMaster i2c; }; #endif

SHS/Temperature_and_humidity/PH20Port.cpp

#include "PH20Port.h" PH20Port_Sig PH20_Port[RJ25_MAX] = { { A3, NC, NC, NC, NC, NC }, //1 { A2, NC, NC, NC, NC, NC }, //2 { A1, NC, NC, NC, NC, NC }, //3 { A0, NC, NC, NC, NC, NC }, //4 { 7, A0, NC, NC, NC, NC }, //5 { 8, A1, NC, NC, NC, NC }, //6 { A5, A4, NC, NC, NC, NC }, //7 { 6, 5, NC, NC, NC, NC }, //8 { 3, NC, NC, NC, NC, NC }, //9 { 4, NC, NC, NC, NC, NC }, //10 { 5, NC, NC, NC, NC, NC }, //11 { 6, NC, NC, NC, NC, NC }, //12 { 4, 7, 8, A3, NC, NC }, //13 { 2, 7, A5, A4, NC, NC }, //14 { NC, NC, 3, 5, 6, NC }, //15 { NC, NC, A4, A5, 2, NC }, //16 }; /***********************Port*********************/ /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here */ PH20Port::PH20Port(void) { s1 = PH20_Port[0].s1; s2 = PH20_Port[0].s2; s3 = PH20_Port[0].s3; s4 = PH20_Port[0].s4; s5 = PH20_Port[0].s5; s6 = PH20_Port[0].s6; _port = 0; } /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here, but PWM frequency set to 976 Hz * \param[in] * port - RJ25 port from PORT_1 to M2 */ PH20Port::PH20Port(uint8_t port) { if (port < 1) return; s1 = PH20_Port[port-1].s1; s2 = PH20_Port[port-1].s2; s3 = PH20_Port[port-1].s3; s4 = PH20_Port[port-1].s4; s5 = PH20_Port[port-1].s5; s6 = PH20_Port[port-1].s6; _port = port; } /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here, but PWM frequency set to 976 Hz * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 */ PH20Port::PH20Port(uint8_t port, uint8_t slot) { if (port < 1) return; s1 = PH20_Port[port-1].s1; s2 = PH20_Port[port-1].s2; _port = port; _slot = slot; } /** * \par Function * getPort * \par Description * Get current valid port of current RJ25 object * \par Output * None * \return * Port bumber from PORT_1 to M2 * \par Others * None */ uint8_t PH20Port::getPort() { return(_port); } /** * \par Function * getSlot * \par Description * Get current valid slot of current RJ25 object's port * \par Output * None * \return * Slot bumber SLOT1 or SLOT2 * \par Others * None */ uint8_t PH20Port::getSlot(void) { return(_slot); } /** * \par Function * dRead1 * \par Description * Read the digital input value on slot1 of current RJ25 object's port * \param[in] * mode - digital input mode INPUT or INPUT_PULLUP * \par Output * None * \return * Digital input value * \par Others * None */ bool PH20Port::dRead1(uint8_t mode) { bool val; pinMode(s1, mode); val = digitalRead(s1); return(val); } /** * \par Function * dRead2 * \par Description * Read the digital input value on slot2 of current RJ25 object's port * \param[in] * mode - digital input mode INPUT or INPUT_PULLUP * \par Output * None * \return * Digital input value * \par Others * None */ bool PH20Port::dRead2(uint8_t mode) { bool val; pinMode(s2, mode); val = digitalRead(s2); return(val); } bool PH20Port::dRead3(uint8_t mode) { bool val; pinMode(s3, mode); val = digitalRead(s3); return(val); } bool PH20Port::dRead4(uint8_t mode) { bool val; pinMode(s4, mode); val = digitalRead(s4); return(val); } bool PH20Port::dRead5(uint8_t mode) { bool val; pinMode(s5, mode); val = digitalRead(s5); return(val); } /** * \par Function * dpRead1 * \par Description * Read the digital input value on slot1 of current RJ25 object's port, the input * mode set as INPUT_PULLUP. * \par Output * None * \return * Digital input value * \par Others * None */ bool PH20Port::dpRead1(void) { bool val; pinMode(s1, INPUT_PULLUP); val = digitalRead(s1); return(val); } /** * \par Function * dpRead2 * \par Description * Read the digital input value on slot2 of current RJ25 object's port, the input * mode set as INPUT_PULLUP. * \par Output * None * \return * Digital input value * \par Others * None */ bool PH20Port::dpRead2(void) { bool val; pinMode(s2, INPUT_PULLUP); val = digitalRead(s2); return(val); } /** * \par Function * dWrite1 * \par Description * Set the digital output value on slot1 of current RJ25 object's port * \param[in] * value - digital output value HIGH or LOW * \par Output * None * \return * None * \par Others * None */ void PH20Port::dWrite1(bool value) { pinMode(s1, OUTPUT); digitalWrite(s1, value); } /** * \par Function * dWrite2 * \par Description * Set the digital output value on slot2 of current RJ25 object's port * \param[in] * value - digital output value HIGH or LOW * \par Output * None * \return * None * \par Others * None */ void PH20Port::dWrite2(bool value) { pinMode(s2, OUTPUT); digitalWrite(s2, value); } void PH20Port::dWrite3(bool value) { pinMode(s3, OUTPUT); digitalWrite(s3, value); } void PH20Port::dWrite4(bool value) { pinMode(s4, OUTPUT); digitalWrite(s4, value); } void PH20Port::dWrite5(bool value) { pinMode(s5, OUTPUT); digitalWrite(s5, value); } /** * \par Function * aRead1 * \par Description * Read the analog value on slot1 of current RJ25 object's port * \par Output * None * \return * Analog value from 0-1023 * \par Others * None */ int16_t PH20Port::aRead1(void) { int16_t val; pinMode(s1, INPUT); val = analogRead(s1); return(val); } /** * \par Function * aRead2 * \par Description * Read the analog value on slot2 of current RJ25 object's port * \par Output * None * \return * Analog value from 0-1023 * \par Others * None */ int16_t PH20Port::aRead2(void) { int16_t val; pinMode(s2, INPUT); val = analogRead(s2); return(val); } int16_t PH20Port::aRead3(void) { int16_t val; pinMode(s3, INPUT); val = analogRead(s3); return(val); } int16_t PH20Port::aRead4(void) { int16_t val; pinMode(s4, INPUT); val = analogRead(s4); return(val); } int16_t PH20Port::aRead5(void) { int16_t val; pinMode(s5, INPUT); val = analogRead(s5); return(val); } /** * \par Function * aWrite1 * \par Description * Set the PWM output value on slot1 of current RJ25 object's port * \param[in] * value - Analog value between 0 to 255 * \par Output * None * \return * None * \par Others * None */ void PH20Port::aWrite1(int16_t value) { analogWrite(s1, value); } /** * \par Function * aWrite2 * \par Description * Set the PWM output value on slot2 of current RJ25 object's port * \param[in] * value - Analog value between 0 to 255 * \par Output * None * \return * None * \par Others * None */ void PH20Port::aWrite2(int16_t value) { analogWrite(s2, value); } void PH20Port::aWrite3(int16_t value) { analogWrite(s3, value); } void PH20Port::aWrite4(int16_t value) { analogWrite(s4, value); } void PH20Port::aWrite5(int16_t value) { analogWrite(s5, value); } /** * \par Function * reset * \par Description * Reset the RJ25 available PIN by its port * \param[in] * port - RJ25 port from PORT_1 to M2 * \par Output * None * \return * None * \par Others * None */ void PH20Port::reset(uint8_t port) { if ( port < 1) return; s1 = PH20_Port[port-1].s1; s2 = PH20_Port[port-1].s2; _port = port; } /** * \par Function * reset * \par Description * Reset the RJ25 available PIN by its port and slot * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 * \par Output * None * \return * None * \par Others * None */ void PH20Port::reset(uint8_t port, uint8_t slot) { if ( port < 1) return; s1 = PH20_Port[port-1].s1; s2 = PH20_Port[port-1].s2; _port = port; _slot = slot; } /** * \par Function * pin1 * \par Description * Return the arduino pin number of current RJ25 object's slot1 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t PH20Port::pin1(void) { return(s1); } /** * \par Function * pin2 * \par Description * Return the arduino pin number of current RJ25 object's slot2 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t PH20Port::pin2(void) { return(s2); } uint8_t PH20Port::pin3(void) { return(s3); } uint8_t PH20Port::pin4(void) { return(s4); } uint8_t PH20Port::pin5(void) { return(s5); } /** * \par Function * pin * \par Description * Return the arduino pin number of current RJ25 object's port, if the RJ25 module * have one available PIN. * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t PH20Port::pin(void) { return(_slot == SLOT_1 ? s1 : s2); } /** * \par Function * pin * \par Description * Return the arduino pin number of current RJ25 object's port * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t PH20Port::pin(uint8_t port, uint8_t slot) { if ( port < 1) return; return(slot == SLOT_1 ? PH20_Port[port-1].s1 : PH20_Port[port-1].s2); }

SHS/Temperature_and_humidity/PH20Port.h

#ifndef _PH20Port_H_ #define _PH20Port_H_ #include <Arduino.h> #include <avr/interrupt.h> #include <avr/io.h> #include <util/delay.h> #include <stdint.h> #include <stdlib.h> #define RJ25_MAX 16 #define P1 1 #define P2 2 #define P3 3 #define P4 4 #define P5 5 #define P6 6 #define P7 7 #define P8 8 #define P9 9 #define P10 10 #define P11 11 #define P12 12 #define P13 13 #define P14 14 #define P15 15 #define P16 16 /** * A structure to represent PH20Port Signal. */ typedef struct { uint8_t s1; uint8_t s2; uint8_t s3; uint8_t s4; uint8_t s5; uint8_t s6; } PH20Port_Sig; extern PH20Port_Sig PH20_Port[RJ25_MAX]; // PH20Port[0] is nonsense #define NC (0) //use UART RX for NULL port #define SLOT1 (1) #define SLOT2 (2) #define SLOT3 (3) #define SLOT4 (4) #define SLOT5 (5) #define SLOT6 (6) #define SLOT_1 SLOT1 #define SLOT_2 SLOT2 #define SLOT_3 SLOT3 #define SLOT_4 SLOT4 #define SLOT_5 SLOT3 #define SLOT_6 SLOT4 #ifndef FALSE #define FALSE (0) #endif #ifndef TRUE #define TRUE (1) #endif /** * Class: PH20Port * * \par Description * Declaration of Class PH20Port */ class PH20Port { public: /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here */ PH20Port(void); /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here, but PWM frequency set to 976 Hz * \param[in] * port - RJ25 port from PORT_1 to M2 */ PH20Port(uint8_t port); /** * Alternate Constructor which can call your own function to map the PH20Port to arduino port, * no pins are used or initialized here, but PWM frequency set to 976 Hz * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 */ PH20Port(uint8_t port, uint8_t slot); /** * \par Function * getPort * \par Description * Get current valid port of current RJ25 object * \par Output * None * \return * Port bumber from PORT_1 to M2 * \par Others * None */ uint8_t getPort(void); /** * \par Function * getSlot * \par Description * Get current valid slot of current RJ25 object's port * \par Output * None * \return * Slot bumber SLOT1 or SLOT2 * \par Others * None */ uint8_t getSlot(void); /** * \par Function * dRead1 * \par Description * Read the digital input value on slot1 of current RJ25 object's port * \param[in] * mode - digital input mode INPUT or INPUT_PULLUP * \par Output * None * \return * Digital input value * \par Others * None */ bool dRead1(uint8_t mode = INPUT); /** * \par Function * dRead2 * \par Description * Read the digital input value on slot2 of current RJ25 object's port * \param[in] * mode - digital input mode INPUT or INPUT_PULLUP * \par Output * None * \return * Digital input value * \par Others * None */ bool dRead2(uint8_t mode = INPUT); bool dRead3(uint8_t mode = INPUT); bool dRead4(uint8_t mode = INPUT); bool dRead5(uint8_t mode = INPUT); /** * \par Function * dpRead1 * \par Description * Read the digital input value on slot1 of current RJ25 object's port, the input * mode set as INPUT_PULLUP. * \par Output * None * \return * Digital input value * \par Others * None */ bool dpRead1(void); /** * \par Function * dpRead2 * \par Description * Read the digital input value on slot2 of current RJ25 object's port, the input * mode set as INPUT_PULLUP. * \par Output * None * \return * Digital input value * \par Others * None */ bool dpRead2(void); /** * \par Function * dWrite1 * \par Description * Set the digital output value on slot1 of current RJ25 object's port * \param[in] * value - digital output value HIGH or LOW * \par Output * None * \return * None * \par Others * None */ void dWrite1(bool value); /** * \par Function * dWrite2 * \par Description * Set the digital output value on slot2 of current RJ25 object's port * \param[in] * value - digital output value HIGH or LOW * \par Output * None * \return * None * \par Others * None */ void dWrite2(bool value); void dWrite3(bool value); void dWrite4(bool value); void dWrite5(bool value); /** * \par Function * aRead1 * \par Description * Read the analog value on slot1 of current RJ25 object's port * \par Output * None * \return * Analog value from 0-1023 * \par Others * None */ int16_t aRead1(void); /** * \par Function * aRead2 * \par Description * Read the analog value on slot2 of current RJ25 object's port * \par Output * None * \return * Analog value from 0-1023 * \par Others * None */ int16_t aRead2(void); int16_t aRead3(void); int16_t aRead4(void); int16_t aRead5(void); /** * \par Function * aWrite1 * \par Description * Set the PWM output value on slot1 of current RJ25 object's port * \param[in] * value - Analog value between 0 to 255 * \par Output * None * \return * None * \par Others * None */ void aWrite1(int16_t value); /** * \par Function * aWrite2 * \par Description * Set the PWM output value on slot2 of current RJ25 object's port * \param[in] * value - Analog value between 0 to 255 * \par Output * None * \return * None * \par Others * None */ void aWrite2(int16_t value); void aWrite3(int16_t value); void aWrite4(int16_t value); void aWrite5(int16_t value); /** * \par Function * reset * \par Description * Reset the RJ25 available PIN by its port * \param[in] * port - RJ25 port from PORT_1 to M2 * \par Output * None * \return * None * \par Others * None */ void reset(uint8_t port); /** * \par Function * reset * \par Description * Reset the RJ25 available PIN by its port and slot * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 * \par Output * None * \return * None * \par Others * None */ void reset(uint8_t port, uint8_t slot); /** * \par Function * pin1 * \par Description * Return the arduino pin number of current RJ25 object's slot1 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t pin1(void); /** * \par Function * pin2 * \par Description * Return the arduino pin number of current RJ25 object's slot2 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t pin2(void); uint8_t pin3(void); uint8_t pin4(void); uint8_t pin5(void); /** * \par Function * pin * \par Description * Return the arduino pin number of current RJ25 object's port, if the RJ25 module * have one available PIN. * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t pin(void); /** * \par Function * pin * \par Description * Return the arduino pin number of current RJ25 object's port * \param[in] * port - RJ25 port from PORT_1 to M2 * \param[in] * slot - SLOT1 or SLOT2 * \par Output * None * \return * The PIN number of arduino * \par Others * None */ uint8_t pin(uint8_t port, uint8_t slot); protected: /** * \par Description * Variables used to store the slot1 gpio number */ uint8_t s1, s2, s3, s4, s5, s6; /** * \par Description * Variables used to store the port */ uint8_t _port; /** * \par Description * Variables used to store the slot */ uint8_t _slot; }; #endif // _RH20Port_H_

SHS/Temperature_and_humidity/SoftI2CMaster.cpp

SHS/Temperature_and_humidity/SoftI2CMaster.cpp

/*
 * SoftI2CMaster.cpp -- Multi-instance software I2C Master library
 * 
 * 
 * 2010-12 Tod E. Kurt, http://todbot.com/blog/
 *
 * This code takes some tricks from:
 *  http://codinglab.blogspot.com/2008/10/i2c-on-avr-using-bit-banging.html
 *
 * 2014, by Testato: update library and examples for follow Wire’s API of Arduino IDE 1.x
 *
 */

#if   ( ARDUINO  >=   100 )
#include   < Arduino . h >
#else
#include   < WProgram . h >
#endif

#include   "SoftI2CMaster.h"

#include   < util / delay . h >
#include   < string . h >

#define   i2cbitdelay  50

#define   I2C_ACK   1  
#define   I2C_NAK   0


#define  i2c_scl_release ()                  \
     * _sclDirReg      &=~  _sclBitMask
#define  i2c_sda_release ()                  \
     * _sdaDirReg      &=~  _sdaBitMask

// sets SCL low and drives output
#define  i2c_scl_lo ()                                  \
                      * _sclPortReg   &=~  _sclBitMask ;   \
                      * _sclDirReg    |=   _sclBitMask ;  

// sets SDA low and drives output
#define  i2c_sda_lo ()                                  \
                      * _sdaPortReg   &=~  _sdaBitMask ;   \
                      * _sdaDirReg    |=   _sdaBitMask ;   

// set SCL high and to input (releases pin) (i.e. change to input,turnon pullup)
#define  i2c_scl_hi ()                                  \
                      * _sclDirReg    &=~  _sclBitMask ;   \
     if ( usePullups )   {   * _sclPortReg   |=   _sclBitMask ;   }  

// set SDA high and to input (releases pin) (i.e. change to input,turnon pullup)
#define  i2c_sda_hi ()                                  \
                      * _sdaDirReg    &=~  _sdaBitMask ;   \
     if ( usePullups )   {   * _sdaPortReg   |=   _sdaBitMask ;   }  


//
// Constructor
//
SoftI2CMaster :: SoftI2CMaster ()
{
     // do nothing, use setPins() later
}
//
SoftI2CMaster :: SoftI2CMaster ( uint8_t sclPin ,  uint8_t sdaPin )  
{
    setPins ( sclPin ,  sdaPin ,   true );
    i2c_init ();
}

//
SoftI2CMaster :: SoftI2CMaster ( uint8_t sclPin ,  uint8_t sdaPin ,  uint8_t pullups )
{
    setPins ( sclPin ,  sdaPin ,  pullups );
    i2c_init ();
}

//
// Turn Arduino pin numbers into PORTx, DDRx, and PINx
//
void   SoftI2CMaster :: setPins ( uint8_t sclPin ,  uint8_t sdaPin ,  uint8_t pullups )
{
    uint8_t port ;
    
    usePullups  =  pullups ;

    _sclPin  =  sclPin ;
    _sdaPin  =  sdaPin ;
    
    _sclBitMask  =  digitalPinToBitMask ( sclPin );
    _sdaBitMask  =  digitalPinToBitMask ( sdaPin );
    
    port  =  digitalPinToPort ( sclPin );
    _sclPortReg   =  portOutputRegister ( port );
    _sclDirReg    =  portModeRegister ( port );

    port  =  digitalPinToPort ( sdaPin );
    _sdaPortReg   =  portOutputRegister ( port );
    _sdaDirReg    =  portModeRegister ( port );
    
}

//
//
//
uint8_t  SoftI2CMaster :: beginTransmission ( uint8_t address )
{
    i2c_start ();
    uint8_t rc  =  i2c_write (( address << 1 )   |   0 );   // clr read bit
     return  rc ;
}

//
uint8_t  SoftI2CMaster :: requestFrom ( uint8_t address )
{
    i2c_start ();
    uint8_t rc  =  i2c_write (( address << 1 )   |   1 );   // set read bit
     return  rc ;
}
//
uint8_t  SoftI2CMaster :: requestFrom ( int  address )
{
     return  requestFrom (   ( uint8_t )  address );
}

//
uint8_t  SoftI2CMaster :: beginTransmission ( int  address )
{
     return  beginTransmission (( uint8_t ) address );
}

//
//
//
uint8_t  SoftI2CMaster :: endTransmission ( void )
{
    i2c_stop ();
     //return ret;  // FIXME
     return   0 ;
}

// must be called in:
// slave tx event callback
// or after beginTransmission(address)
uint8_t  SoftI2CMaster :: write ( uint8_t data )
{
     return  i2c_write ( data );
}

// must be called in:
// slave tx event callback
// or after beginTransmission(address)
void   SoftI2CMaster :: write ( uint8_t *  data ,  uint8_t quantity )
{
     for ( uint8_t i  =   0 ;  i  <  quantity ;   ++ i ){
        write ( data [ i ]);
     }
}

// must be called in:
// slave tx event callback
// or after beginTransmission(address)
void   SoftI2CMaster :: write ( char *  data )
{
    write (( uint8_t * ) data ,  strlen ( data ));
}

// must be called in:
// slave tx event callback
// or after beginTransmission(address)
void   SoftI2CMaster :: write ( int  data )
{
    write (( uint8_t ) data );
}

//--------------------------------------------------------------------


void   SoftI2CMaster :: i2c_writebit (  uint8_t c  )
{
     if   (  c  >   0   )   {
        i2c_sda_hi ();
     }   else   {
        i2c_sda_lo ();
     }

    i2c_scl_hi ();
    _delay_us ( i2cbitdelay );

    i2c_scl_lo ();
    _delay_us ( i2cbitdelay );

     if   (  c  >   0   )   {
        i2c_sda_lo ();
     }
    _delay_us ( i2cbitdelay );
}

//
uint8_t  SoftI2CMaster :: i2c_readbit ( void )
{
    i2c_sda_hi ();
    i2c_scl_hi ();
    _delay_us ( i2cbitdelay );

    uint8_t port  =  digitalPinToPort ( _sdaPin );
     volatile  uint8_t *  pinReg  =  portInputRegister ( port );
    uint8_t c  =   * pinReg ;    // I2C_PIN;

    i2c_scl_lo ();
    _delay_us ( i2cbitdelay );

     return   (  c  &  _sdaBitMask )   ?   1   :   0 ;
}

// Inits bitbanging port, must be called before using the functions below
//
void   SoftI2CMaster :: i2c_init ( void )
{
     //I2C_PORT &=~ (_BV( I2C_SDA ) | _BV( I2C_SCL ));
     //*_sclPortReg &=~ (_sdaBitMask | _sclBitMask);
    i2c_sda_hi ();
    i2c_scl_hi ();
    
    _delay_us ( i2cbitdelay );
}

// Send a START Condition
//
void   SoftI2CMaster :: i2c_start ( void )
{
     // set both to high at the same time
     //I2C_DDR &=~ (_BV( I2C_SDA ) | _BV( I2C_SCL ));
     //*_sclDirReg &=~ (_sdaBitMask | _sclBitMask);
    i2c_sda_hi ();
    i2c_scl_hi ();

    _delay_us ( i2cbitdelay );
   
    i2c_sda_lo ();
    _delay_us ( i2cbitdelay );

    i2c_scl_lo ();
    _delay_us ( i2cbitdelay );
}

void   SoftI2CMaster :: i2c_repstart ( void )
{
     // set both to high at the same time (releases drive on both lines)
     //I2C_DDR &=~ (_BV( I2C_SDA ) | _BV( I2C_SCL ));
     //*_sclDirReg &=~ (_sdaBitMask | _sclBitMask);
    i2c_sda_hi ();
    i2c_scl_hi ();

    i2c_scl_lo ();                             // force SCL low
    _delay_us ( i2cbitdelay );

    i2c_sda_release ();                        // release SDA
    _delay_us ( i2cbitdelay );

    i2c_scl_release ();                        // release SCL
    _delay_us ( i2cbitdelay );

    i2c_sda_lo ();                             // force SDA low
    _delay_us ( i2cbitdelay );
}

// Send a STOP Condition
//
void   SoftI2CMaster :: i2c_stop ( void )
{
    i2c_scl_hi ();
    _delay_us ( i2cbitdelay );

    i2c_sda_hi ();
    _delay_us ( i2cbitdelay );
}

// write a byte to the I2C slave device
//
uint8_t  SoftI2CMaster :: i2c_write (  uint8_t c  )
{
     for   (  uint8_t i = 0 ; i < 8 ; i ++ )   {
        i2c_writebit (  c  &   128   );
        c <<= 1 ;
     }

     return  i2c_readbit ();
}

// read a byte from the I2C slave device
//
uint8_t  SoftI2CMaster :: i2c_read (  uint8_t ack  )
{
    uint8_t res  =   0 ;

     for   (  uint8_t i = 0 ; i < 8 ; i ++ )   {
        res  <<=   1 ;
        res  |=  i2c_readbit ();   
     }

     if   (  ack  )
        i2c_writebit (   0   );
     else
        i2c_writebit (   1   );

    _delay_us ( i2cbitdelay );

     return  res ;
}

// FIXME: this isn't right, surely
uint8_t  SoftI2CMaster :: read (  uint8_t ack  )
{
   return  i2c_read (  ack  );
}

//
uint8_t  SoftI2CMaster :: read ()
{
     return  i2c_read (  I2C_ACK  );
}

//
uint8_t  SoftI2CMaster :: readLast ()
{
     return  i2c_read (  I2C_NAK  );
}

SHS/Temperature_and_humidity/SoftI2CMaster.h

/* * SoftI2CMaster.h -- Multi-instance software I2C Master library * * 2010-2012 Tod E. Kurt, http://todbot.com/blog/ * 2014, by Testato: update library and examples for follow Wire’s API of Arduino IDE 1.x * */ #ifndef SoftI2CMaster_h #define SoftI2CMaster_h #include <inttypes.h> #define _SOFTI2CMASTER_VERSION 13 // software version of this library class SoftI2CMaster { private: // per object data uint8_t _sclPin; uint8_t _sdaPin; uint8_t _sclBitMask; uint8_t _sdaBitMask; volatile uint8_t *_sclPortReg; volatile uint8_t *_sdaPortReg; volatile uint8_t *_sclDirReg; volatile uint8_t *_sdaDirReg; uint8_t usePullups; // private methods void i2c_writebit( uint8_t c ); uint8_t i2c_readbit(void); void i2c_init(void); void i2c_start(void); void i2c_repstart(void); void i2c_stop(void); uint8_t i2c_write( uint8_t c ); uint8_t i2c_read( uint8_t ack ); public: // public methods SoftI2CMaster(); SoftI2CMaster(uint8_t sclPin, uint8_t sdaPin); SoftI2CMaster(uint8_t sclPin, uint8_t sdaPin, uint8_t usePullups); void setPins(uint8_t sclPin, uint8_t sdaPin, uint8_t usePullups); uint8_t beginTransmission(uint8_t address); uint8_t beginTransmission(int address); uint8_t endTransmission(void); uint8_t write(uint8_t); void write(uint8_t*, uint8_t); void write(int); void write(char*); void begin(void) {return;}; uint8_t requestFrom(int address); uint8_t requestFrom(uint8_t address); uint8_t read( uint8_t ack ); uint8_t read(); uint8_t readLast(); }; #endif

SHS/Temperature_and_humidity/Temperature_and_humidity.ino

#include "SoftI2CMaster.h" #include "LiquidCrystal_SoftI2C.h" #include "DHT.h" LiquidCrystal_SoftI2C mylcd(0x27,16,2,7,A0); DHT dhtA3(A3, 11); void setup(){ Serial.begin(9600); dhtA3.begin(); mylcd.begin(16, 2); pinMode(5, OUTPUT); pinMode(6, OUTPUT); } void loop(){ float t = dhtA3.readTemperature(); float h = dhtA3.readHumidity(); mylcd.setCursor(0, 0); mylcd.print("Temp: "); mylcd.print(dhtA3.readTemperature()); mylcd.print("C"); Serial.print("Temp: "); Serial.print(t); Serial.println(" *C "); mylcd.setCursor(0, 1); mylcd.print("Humdity:"); mylcd.print(dhtA3.readHumidity()); mylcd.print("%"); Serial.print("Hum: "); Serial.print(h); Serial.print(" %\t"); delay(3000); if (dhtA3.readTemperature() > 30 || dhtA3.readHumidity() > 70) { digitalWrite(5,HIGH); digitalWrite(6,LOW); } else { digitalWrite(5,LOW); digitalWrite(6,LOW); } }

SHS/zhinengchuang_rain/TM1650.h

/** ============================================ * 7 segment display driver for JY-MCU module based on TM1650 chip * Copyright (c) 2015 Anatoli Arkhipenko * * * Changelog: * v1.0.0: * 2015-02-24 - Initial release * * v1.0.1: * 2015-04-27 - Added support of program memery (PROGMEM) to store the ASCII to Segment Code table * * v1.0.2: * 2015-08-08 - Added check if panel is connected during init. All calls will be disabled is panel was not connected during init. * * v1.1.0: * 2015-12-20 - code clean up. Moved to a single header file. Added Gradual brightness method * * ===============================================*/ #include <Arduino.h> #include <Wire.h> #ifndef _TM1650_H_ #define _TM1650_H_ #define TM1650_USE_PROGMEM #ifdef TM1650_USE_PROGMEM #include <avr/pgmspace.h> #endif #define TM1650_DISPLAY_BASE 0x34 // Address of the left-most digit #define TM1650_DCTRL_BASE 0x24 // Address of the control register of the left-most digit #define TM1650_NUM_DIGITS 16 // max number of digits #define TM1650_MAX_STRING 128 // number of digits #define TM1650_BIT_ONOFF 0b00000001 #define TM1650_MSK_ONOFF 0b11111110 #define TM1650_BIT_DOT 0b00000001 #define TM1650_MSK_DOT 0b11110111 #define TM1650_BRIGHT_SHIFT 4 #define TM1650_MSK_BRIGHT 0b10001111 #define TM1650_MIN_BRIGHT 0 #define TM1650_MAX_BRIGHT 7 #ifndef TM1650_USE_PROGMEM const byte TM1650_CDigits[128] { #else const PROGMEM byte TM1650_CDigits[128] { #endif //0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 0x00, 0x82, 0x21, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x0F, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, // 0x20 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7f, 0x6f, 0x00, 0x00, 0x00, 0x48, 0x00, 0x53, // 0x30 0x00, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x6F, 0x76, 0x06, 0x1E, 0x00, 0x38, 0x00, 0x54, 0x3F, // 0x40 0x73, 0x67, 0x50, 0x6D, 0x78, 0x3E, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x39, 0x00, 0x0F, 0x00, 0x08, // 0x50 0x63, 0x5F, 0x7C, 0x58, 0x5E, 0x7B, 0x71, 0x6F, 0x74, 0x02, 0x1E, 0x00, 0x06, 0x00, 0x54, 0x5C, // 0x60 0x73, 0x67, 0x50, 0x6D, 0x78, 0x1C, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x39, 0x30, 0x0F, 0x00, 0x00 // 0x70 }; class TM1650 { public: TM1650(unsigned int aNumDigits = 4); void init(); void clear(); void displayOn(); void displayOff(); void displayState(bool aState); void displayString(char *aString); void displayString(String aString); void displayString(float value); void displayString(int value); void displayString(long value); int displayRunning(char *aString); int displayRunningShift(); void setBrightness(unsigned int aValue = TM1650_MAX_BRIGHT); void setBrightnessGradually(unsigned int aValue = TM1650_MAX_BRIGHT); inline unsigned int getBrightness() { return iBrightness; }; void controlPosition(unsigned int aPos, byte aValue); void setPosition(unsigned int aPos, byte aValue); void setDot(unsigned int aPos, bool aState); byte getPosition(unsigned int aPos) { return iBuffer[aPos]; }; inline unsigned int getNumPositions() { return iNumDigits; }; private: char *iPosition; bool iActive; unsigned int iNumDigits; unsigned int iBrightness; char iString[TM1650_MAX_STRING+1]; byte iBuffer[TM1650_NUM_DIGITS+1]; byte iCtrl[TM1650_NUM_DIGITS]; }; // ---- Implementation ---- /** Constructor, uses default values for the parameters * so could be called with no parameters. * aNumDigits - number of display digits (default = 4) */ TM1650::TM1650(unsigned int aNumDigits) { iNumDigits = (aNumDigits > TM1650_NUM_DIGITS) ? TM1650_NUM_DIGITS : aNumDigits; } /** Initialization * initializes the driver. Turns display on, but clears all digits. */ void TM1650::init() { iPosition = NULL; for (int i=0; i<iNumDigits; i++) { iBuffer[i] = 0; iCtrl[i] = 0; } Wire.beginTransmission(TM1650_DISPLAY_BASE); iActive = (Wire.endTransmission() == 0); clear(); displayOn(); } /** Set brightness of all digits equally * aValue - brightness value with 1 being the lowest, and 7 being the brightest */ void TM1650::setBrightness(unsigned int aValue) { if (!iActive) return; iBrightness = (aValue > TM1650_MAX_BRIGHT) ? TM1650_MAX_BRIGHT : aValue; for (int i=0; i<iNumDigits; i++) { Wire.beginTransmission(TM1650_DCTRL_BASE+i); iCtrl[i] = (iCtrl[i] & TM1650_MSK_BRIGHT) | ( iBrightness << TM1650_BRIGHT_SHIFT ); Wire.write((byte) iCtrl[i]); Wire.endTransmission(); } } /** Set brightness of all digits equally * aValue - brightness value with 1 being the lowest, and 7 being the brightest */ void TM1650::setBrightnessGradually(unsigned int aValue) { if (!iActive || aValue == iBrightness) return; if (aValue > TM1650_MAX_BRIGHT) aValue = TM1650_MAX_BRIGHT; int step = (aValue < iBrightness) ? -1 : 1; unsigned int i = iBrightness; do { setBrightness(i); delay(50); i += step; } while (i!=aValue); } /** Turns display on or off according to aState */ void TM1650::displayState (bool aState) { if (aState) displayOn (); else displayOff(); } /** Turns the display on */ void TM1650::displayOn () // turn all digits on { if (!iActive) return; for (int i=0; i<iNumDigits; i++) { Wire.beginTransmission(TM1650_DCTRL_BASE+i); iCtrl[i] = (iCtrl[i] & TM1650_MSK_ONOFF) | TM1650_BIT_DOT; Wire.write((byte) iCtrl[i]); Wire.endTransmission(); } } /** Turns the display off */ void TM1650::displayOff () // turn all digits off { if (!iActive) return; for (int i=0; i<iNumDigits; i++) { Wire.beginTransmission(TM1650_DCTRL_BASE+i); iCtrl[i] = (iCtrl[i] & TM1650_MSK_ONOFF); Wire.write((byte) iCtrl[i]); Wire.endTransmission(); } } /** Directly write to the CONTROL register of the digital position * aPos = position to set the control register for * aValue = value to write to the position * * Internal control buffer is updated as well */ void TM1650::controlPosition(unsigned int aPos, byte aValue) { if (!iActive) return; if (aPos < iNumDigits) { Wire.beginTransmission(TM1650_DCTRL_BASE + (int) aPos); iCtrl[aPos] = aValue; Wire.write(aValue); Wire.endTransmission(); } } /** Directly write to the digit register of the digital position * aPos = position to set the digit register for * aValue = value to write to the position * * Internal position buffer is updated as well */ void TM1650::setPosition(unsigned int aPos, byte aValue) { if (!iActive) return; if (aPos < iNumDigits) { Wire.beginTransmission(TM1650_DISPLAY_BASE + (int) aPos); iBuffer[aPos] = aValue; Wire.write(aValue); Wire.endTransmission(); } } /** Directly set/clear a 'dot' next to a specific position * aPos = position to set/clear the dot for * aState = display the dot if true, clear if false * * Internal buffer is updated as well */ void TM1650::setDot(unsigned int aPos, bool aState) { iBuffer[aPos] = iBuffer[aPos] & 0x7F |(aState ? 0b10000000 : 0); setPosition(aPos, iBuffer[aPos]); } /** Clear all digits. Keep the display on. */ void TM1650::clear() // clears all digits { if (!iActive) return; for (int i=0; i<iNumDigits; i++) { Wire.beginTransmission(TM1650_DISPLAY_BASE+i); iBuffer[i] = 0; Wire.write((byte) 0); Wire.endTransmission(); } } /** Display string on the display * aString = character array to be displayed * * Internal buffer is updated as well * Only first N positions of the string are displayed if * the string is longer than the number of digits */ void TM1650::displayString(char *aString) { if (!iActive) return; unsigned int slen =strlen(aString); String bString = aString; for (int i = 0; i < 4 - slen; i++) bString = " " + bString; for (int i = 0; i<iNumDigits; i++) { byte a = ((byte)bString.charAt(i)) & 0b01111111; byte dot = ((byte)bString.charAt(i)) & 0b10000000; #ifndef TM1650_USE_PROGMEM iBuffer[i] = TM1650_CDigits[a]; #else iBuffer[i] = pgm_read_byte_near(TM1650_CDigits + a); #endif if (a) { Wire.beginTransmission(TM1650_DISPLAY_BASE + i); Wire.write(iBuffer[i] | dot); Wire.endTransmission(); } else break; } } void TM1650::displayString(String aString) { if (!iActive) return; unsigned int slen = aString.length(); for (int i = 0; i < 4 - slen; i++) aString = " " + aString; for (int i = 0; i<iNumDigits; i++) { byte a = ((byte)aString.charAt(i)) & 0b01111111; byte dot = ((byte)aString.charAt(i)) & 0b10000000; #ifndef TM1650_USE_PROGMEM iBuffer[i] = TM1650_CDigits[a]; #else iBuffer[i] = pgm_read_byte_near(TM1650_CDigits + a); #endif if (a) { Wire.beginTransmission(TM1650_DISPLAY_BASE + i); Wire.write(iBuffer[i] | dot); Wire.endTransmission(); } else break; } } void TM1650::displayString(float value) { if (!iActive) return; String aString = String("") + value; aString = aString + "_"; aString.replace("000_", ""); aString.replace("00_", ""); aString.replace("0_", ""); unsigned int slen = aString.length(); for (int i = 0; i < 4 - slen; i++) aString = " " + aString; for (int i = 0; i<iNumDigits; i++) { byte a = ((byte)aString.charAt(i)) & 0b01111111; byte dot = ((byte)aString.charAt(i)) & 0b10000000; #ifndef TM1650_USE_PROGMEM iBuffer[i] = TM1650_CDigits[a]; #else iBuffer[i] = pgm_read_byte_near(TM1650_CDigits + a); #endif if (a) { Wire.beginTransmission(TM1650_DISPLAY_BASE + i); Wire.write(iBuffer[i] | dot); Wire.endTransmission(); } else break; } } void TM1650::displayString(int value) { if (!iActive) return; String aString = String("") + value; unsigned int slen = aString.length(); for (int i = 0; i < 4 - slen; i++) aString = " " + aString; for (int i = 0; i<iNumDigits; i++) { byte a = ((byte)aString.charAt(i)) & 0b01111111; byte dot = ((byte)aString.charAt(i)) & 0b10000000; #ifndef TM1650_USE_PROGMEM iBuffer[i] = TM1650_CDigits[a]; #else iBuffer[i] = pgm_read_byte_near(TM1650_CDigits + a); #endif if (a) { Wire.beginTransmission(TM1650_DISPLAY_BASE + i); Wire.write(iBuffer[i] | dot); Wire.endTransmission(); } else break; } } void TM1650::displayString(long value) { displayString((int)value); } /** Display string on the display in a running fashion * aString = character array to be displayed * * Starts with first N positions of the string. * Subsequent characters are displayed with 1 char shift each time displayRunningShift() is called * * returns: number of iterations remaining to display the whole string */ int TM1650::displayRunning(char *aString) { strncpy(iString, aString, TM1650_MAX_STRING+1); iPosition = iString; iString[TM1650_MAX_STRING] = '\0'; //just in case. displayString(iPosition); int l = strlen(iPosition); if (l <= iNumDigits) return 0; return (l - iNumDigits); } /** Display next segment (shifting to the left) of the string set by displayRunning() * Starts with first N positions of the string. * Subsequent characters are displayed with 1 char shift each time displayRunningShift is called * * returns: number of iterations remaining to display the whole string */ int TM1650::displayRunningShift() { if (strlen(iPosition) <= iNumDigits) return 0; displayString(++iPosition); return (strlen(iPosition) - iNumDigits); } #endif /* _TM1650_H_ */

SHS/zhinengchuang_rain/zhinengchuang_rain.ino

#include <Wire.h> #include "TM1650.h" #include <Servo.h> TM1650 tm_4display; volatile int _light; volatile int yudi; volatile int item; Servo servo_13; void setup(){ Serial.begin(9600); Wire.begin(); tm_4display.init(); _light = 0; yudi = 0; item = 0; tm_4display.clear(); servo_13.attach(13); } void loop(){ _light = analogRead(A2); yudi = analogRead(A1); tm_4display.displayString(_light); Serial.print(String(" light:") + String(_light)); Serial.print(","); Serial.println(String("yudi:") + String(yudi)); delay(500); if (_light > 100) { if (yudi < 300) { servo_13.write(90); delay(300); } else { servo_13.write(0); delay(3000); } } else { servo_13.write(90); delay(20); } }