Advertisement
Guest User

Untitled

a guest
Apr 22nd, 2019
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 15.23 KB | None | 0 0
  1. #include "EduIntro.h"
  2.  
  3. #if USB_VID == 0x2341 && USB_PID == 0x803C
  4. #include <Esplora.h>
  5. #endif
  6.  
  7. /*
  8. -----------------------------------------------------------------------------
  9.                                    Definitions
  10. -----------------------------------------------------------------------------
  11. */
  12.  
  13. /* for DHT11 serialized input */
  14.  
  15. #define BITS_IN(object) (8 * sizeof((object)))
  16.  
  17. enum {
  18.     /*
  19.      * Time required to signal the DHT11 to switch from low power mode to
  20.      * running mode.  18 ms is the minimal, add a few extra ms to be safe.
  21.      */
  22.     START_SIGNAL_WAIT = 20,
  23.  
  24.     /*
  25.      * Once the start signal has been sent, we wait for a response.  The doc
  26.      * says this should take 20-40 us, we wait 5 ms to be safe.
  27.      */
  28.     RESPONSE_WAIT =  30,
  29.  
  30.     /*
  31.      * The time threshold between a 0 bit and a 1 bit in the response.  Times
  32.      * greater than this (in ms) will be considered a 1; otherwise they'll be
  33.      * considered a 0.
  34.      */
  35.     ONE_THRESHOLD = 40,
  36.  
  37.     /*
  38.      * The number of bytes we expect from the sensor.  This consists of one
  39.      * byte for the integral part of the humidity, one byte for the fractional
  40.      * part of the humidity, one byte for the integral part of the temperature,
  41.      * one byte for the fractional part of the temperature, and one byte for
  42.      * a checksum.  The DHT11 doesn't capture the fractional parts of the
  43.      * temperature and humidity, but it doesn't transmit data during those
  44.      * times.
  45.      */
  46.     RESPONSE_SIZE =  5,
  47.  
  48.     /*
  49.      * The number of bits in a bytes.
  50.      */
  51.     BITS_PER_BYTE =  8,
  52.  
  53.     /*
  54.      * The 0-base most significant bit in a byte.
  55.      */
  56.     BYTE_MS_BIT =  7,
  57.  
  58.     /*
  59.      * The index in the response where the humidity reading is stored.
  60.      */
  61.     HUMIDITY_INDEX =  0,
  62.  
  63.     /*
  64.      * The index in the response where the temperature is stored.
  65.      */
  66.     TEMPERATURE_INDEX =  2,
  67.  
  68.     /*
  69.      * The index in the response where the checksum is stored.
  70.      */
  71.     CHECKSUM_INDEX =  4,
  72. };
  73.  
  74. /*
  75.  -----------------------------------------------------------------------------
  76.                                     Generals
  77.  -----------------------------------------------------------------------------
  78. */
  79.  
  80. /*      Digital Input       */
  81.  
  82. DigitalInput::DigitalInput(uint8_t _pin)
  83. {
  84.     pin = _pin;
  85.     pinMode(pin, INPUT);
  86. }
  87.  
  88. DigitalInput::DigitalInput(uint8_t _pin, uint8_t _mode)
  89. {
  90.     pin = _pin;
  91.     pinMode(pin, _mode);
  92. }
  93.  
  94. boolean DigitalInput::read() {
  95.  
  96.     boolean val;
  97.  
  98.     #if USB_VID == 0x2341 && USB_PID == 0x803C
  99.         int value = Esplora.readTK(pin);
  100.         if (value < 128)
  101.             val = 0;
  102.         else
  103.             val = 1;
  104.     #else
  105.         val = digitalRead(pin);
  106.     #endif
  107.  
  108.     return val;
  109. }
  110.  
  111.  
  112. /*      Analog Input        */
  113.  
  114. AnalogInput::AnalogInput(uint8_t _pin)
  115. {
  116.     pin = _pin;
  117. }
  118.  
  119. int AnalogInput::read() {
  120.  
  121.     int val;
  122.  
  123.     #if USB_VID == 0x2341 && USB_PID == 0x803C
  124.         val = Esplora.readTK(pin);
  125.     #else
  126.         val = analogRead(pin);
  127.     #endif
  128.  
  129.     if (val > _oldVal)
  130.     {
  131.       _increasing = true;
  132.       _decreasing = false;
  133.     }
  134.  
  135.     if (val < _oldVal)
  136.     {
  137.       _increasing = false;
  138.       _decreasing = true;
  139.     }
  140.  
  141.     _oldVal = val;
  142.  
  143.     return val;
  144. }
  145.  
  146. boolean AnalogInput::increasing() {
  147.     AnalogInput::read();
  148.     return _increasing;
  149. }
  150.  
  151. boolean AnalogInput::decreasing() {
  152.     AnalogInput::read();
  153.     return _decreasing;
  154. }
  155.  
  156. /*      Analog Input with two connectors       */
  157.  
  158. AnalogInput2::AnalogInput2(uint8_t _pinX, uint8_t _pinY)
  159. {
  160.     pinX = _pinX;
  161.     pinY = _pinY;
  162. }
  163.  
  164. AnalogInput2::AnalogInput2(uint8_t _pinX, uint8_t _pinY, uint8_t _pinZ)
  165. {
  166.     pinX = _pinX;
  167.     pinY = _pinY;
  168.     pinZ = _pinZ;
  169. }
  170.  
  171. int AnalogInput2::readX() {
  172.  
  173.     int val;
  174.  
  175.     #if USB_VID == 0x2341 && USB_PID == 0x803C
  176.         val = Esplora.readTK(pinX);
  177.     #else
  178.         val = analogRead(pinX);
  179.     #endif
  180.  
  181.     return val;
  182. }
  183.  
  184. int AnalogInput2::readY() {
  185.  
  186.     int val;
  187.  
  188.     #if USB_VID == 0x2341 && USB_PID == 0x803C
  189.         val = Esplora.readTK(pinY);
  190.     #else
  191.         val = analogRead(pinY);
  192.     #endif
  193.  
  194.     return val;
  195. }
  196.  
  197. int AnalogInput2::readZ() {
  198.  
  199.     int val;
  200.  
  201.     #if USB_VID == 0x2341 && USB_PID == 0x803C
  202.         val = Esplora.readTK(pinZ);
  203.     #else
  204.         val = analogRead(pinZ);
  205.     #endif
  206.  
  207.     return val;
  208. }
  209.  
  210. /*      Output       */
  211.  
  212. Output::Output(uint8_t _pin)
  213. {
  214.   pin = _pin;
  215.     _state = LOW;
  216.     pinMode(pin, OUTPUT);
  217. }
  218.  
  219. boolean Output::isPWM()
  220. {
  221.   if (pin == D11 || pin == D10 || pin == D9 || pin == D6 || pin == D5 || pin == D3)
  222.     return true;
  223.   return false;
  224. }
  225.  
  226. void Output::write(int value)
  227. {
  228.   if (isPWM())
  229.     if( value <= ANALOG_MAX && value >= 0 )
  230.         analogWrite(pin, value * 0.25); // make sure the value is constrained between 0..255
  231.     else
  232.         return;
  233.   else
  234.     if ( value > ANALOG_MAX * 0.5 )
  235.       digitalWrite(pin, HIGH);
  236.     else
  237.       digitalWrite(pin, LOW);
  238. }
  239.  
  240. void Output::on() {
  241.     write(1023);
  242.     _state = HIGH;
  243. }
  244.  
  245. void Output::off() {
  246.     write(0);
  247.     _state = LOW;
  248. }
  249.  
  250.  
  251. void Output::blink(int del)
  252. {
  253.     on();
  254.     delay(del);
  255.     off();
  256.     delay(del);
  257. }
  258.  
  259. void Output::blink(int del1, int del2)
  260. {
  261.     on();
  262.     delay(del1);
  263.     off();
  264.     delay(del2);
  265. }
  266.  
  267. /*
  268.  -----------------------------------------------------------------------------
  269.                                 Digital Inputs
  270.  -----------------------------------------------------------------------------
  271.  */
  272.  
  273. /*      Button      */
  274. /*
  275.    The button is considered to be using the chip's internal pull-up
  276.    which means that by default, it should be HIGH; LOW when pressed
  277. */
  278. Button::Button(uint8_t _pin) : DigitalInput(_pin, INPUT_PULLUP)
  279. {
  280.     _toggleState = LOW;
  281.     _oldState = LOW;
  282.     _pressedState = LOW;
  283.     _releasedState = LOW;
  284.     _heldState = LOW;
  285.   _heldTime = 500;
  286. }
  287.  
  288. void Button::update() {
  289.   boolean newState = Button::read();
  290.   if (newState != _oldState) {
  291.     // pressed?
  292.     if (newState == HIGH) {
  293.       _pressedState = true;
  294.     }
  295.     else {
  296.       _releasedState = true;
  297.      _toggleState = !_toggleState;
  298.     }
  299.  
  300.     _oldState = newState;
  301.     delay(50); // debouncing
  302.   }
  303.  
  304.   else {
  305.  
  306.       int timeDiff = millis() - _millisMark;
  307.  
  308.       if(newState == HIGH && _oldState == HIGH && timeDiff > _heldTime) {
  309.         _heldState = true;
  310.     } else {
  311.         _heldState = false;
  312.     }
  313.   }
  314. }
  315.  
  316.  
  317. boolean Button::readSwitch()
  318. {
  319.     Button::update();
  320.     return _toggleState;
  321. }
  322.  
  323. boolean Button::pressed()
  324. {
  325.     Button::update();
  326.  
  327.     if(_pressedState == true)
  328.     {
  329.         _millisMark = millis();
  330.         _pressedState = false;
  331.         return true;
  332.     }
  333.     else
  334.         return false;
  335. }
  336.  
  337. boolean Button::released()
  338. {
  339.     Button::update();
  340.  
  341.     if(_releasedState == true)
  342.     {
  343.         _releasedState = false;
  344.         return true;
  345.     }
  346.     else
  347.         return false;
  348. }
  349.  
  350. boolean Button::held()
  351. {
  352.     Button::update();
  353.     return _heldState;
  354. }
  355.  
  356. /*      PIR      */
  357. /*
  358.    The PIR could be in need of the internal pull-up or not
  359.    therefore the need of two constructors. By default: no pull-up
  360. */
  361. PIR::PIR(uint8_t _pin) : DigitalInput(_pin, INPUT)
  362. {
  363.     _toggleState = LOW;
  364.     _oldState = LOW;
  365.     _pressedState = LOW;
  366.     _releasedState = LOW;
  367.     _heldState = LOW;
  368.   _heldTime = 500;
  369.   _mode = INPUT;
  370. }
  371.  
  372. PIR::PIR(uint8_t _pin, uint8_t _mod) : DigitalInput(_pin, _mod)
  373. {
  374.   if(_mode == INPUT_PULLUP) {
  375.     _toggleState = HIGH;
  376.     _oldState = HIGH;
  377.     _pressedState = HIGH;
  378.     _releasedState = HIGH;
  379.     _heldState = HIGH;
  380.   } else {
  381.     _toggleState = LOW;
  382.     _oldState = LOW;
  383.     _pressedState = LOW;
  384.     _releasedState = LOW;
  385.     _heldState = LOW;
  386.   }
  387.   _heldTime = 500;
  388.   _mode = _mod;
  389. }
  390.  
  391. void PIR::update() {
  392.   boolean newState = PIR::read();
  393.   if (newState != _oldState) {
  394.     _activityState = true; // there was some sort of activity
  395.     // activated?
  396.     if(_mode == INPUT_PULLUP) {
  397.       if (newState == LOW) {
  398.         _pressedState = true;
  399.       }
  400.       else {
  401.         _releasedState = true;
  402.        _toggleState = !_toggleState;
  403.       }
  404.     } else {
  405.       if (newState == HIGH) {
  406.         _pressedState = true;
  407.       }
  408.       else {
  409.         _releasedState = true;
  410.        _toggleState = !_toggleState;
  411.       }
  412.     }
  413.     _oldState = newState;
  414.     //delay(50); // debouncing is unlike in the button not needed, but this is up for testing
  415.   }
  416.  
  417.   else {
  418.  
  419.     int timeDiff = millis() - _millisMark;
  420.  
  421.     if(_mode == INPUT_PULLUP) {
  422.       if(newState == LOW && _oldState == LOW && timeDiff > _heldTime) {
  423.             _heldState = true;
  424.       } else {
  425.             _heldState = false;
  426.       }
  427.     } else {
  428.       if(newState == HIGH && _oldState == HIGH && timeDiff > _heldTime) {
  429.             _heldState = true;
  430.       } else {
  431.             _heldState = false;
  432.       }
  433.     }
  434.   }
  435. }
  436.  
  437. boolean PIR::hadActivity() {
  438.   return _activityState;
  439. }
  440.  
  441. boolean PIR::resetActivity() {
  442.   _activityState = false;
  443.   return _activityState;
  444. }
  445.  
  446. boolean PIR::readSwitch()
  447. {
  448.     PIR::update();
  449.     return _toggleState;
  450. }
  451.  
  452. boolean PIR::activated()
  453. {
  454.     PIR::update();
  455.  
  456.     if(_pressedState == true)
  457.     {
  458.     _millisMark = millis();
  459.         _pressedState = false;
  460.         return true;
  461.     }
  462.     else
  463.         return false;
  464. }
  465.  
  466. boolean PIR::deactivated()
  467. {
  468.     PIR::update();
  469.  
  470.     if(_releasedState == true)
  471.     {
  472.         _releasedState = false;
  473.         return true;
  474.     }
  475.     else
  476.         return false;
  477. }
  478.  
  479. boolean PIR::active()
  480. {
  481.     PIR::update();
  482.     return _heldState;
  483. }
  484.  
  485. /* DHT 11 temperature sensor */
  486.  
  487. DHT11::DHT11(uint8_t _pin) : DigitalInput(_pin, INPUT)
  488. {
  489.   pin = _pin;
  490. }
  491.  
  492. DHT11::ReadStatus DHT11::update() {
  493.     uint8_t    buffer[RESPONSE_SIZE] = { 0 };
  494.     uint8_t    bitIndex              = BYTE_MS_BIT;
  495.     ReadStatus status                = OK;
  496.  
  497.     // Request sample
  498.     pinMode(this->pin, OUTPUT);
  499.     digitalWrite(this->pin, LOW);
  500.     delay(START_SIGNAL_WAIT);
  501.  
  502.     // Wait for response
  503.     digitalWrite(this->pin, HIGH);
  504.     pinMode(this->pin, INPUT);
  505.     delayMicroseconds(RESPONSE_WAIT);
  506.  
  507.     // Acknowledge or timeout
  508.     // Response signal should first be low for 80us...
  509.     if ((status = this->waitForPinChange(LOW)) != OK) {
  510.         goto done;
  511.     }
  512.  
  513.     // ... then be high for 80us ...
  514.     if ((status = this->waitForPinChange(HIGH)) != OK) {
  515.         goto done;
  516.     }
  517.  
  518.     /*
  519.      * ... then provide 5 bytes of data that include the integral part of the
  520.      * humidity, the fractional part of the humidity, the integral part of the
  521.      * temperature, the fractional part of the temperature, and a checksum
  522.      * that is the sum of the integral parts of humidity and temperature.
  523.      */
  524.     for (size_t i = 0; i < BITS_IN(buffer); i++) {
  525.         if ((status = this->waitForPinChange(LOW)) != OK) {
  526.             goto done;
  527.         }
  528.  
  529.         unsigned long highStart = micros();
  530.  
  531.         if ((status = this->waitForPinChange(HIGH)) != OK) {
  532.             goto done;
  533.         }
  534.  
  535.         // 26-28 us = 0, 50 us = 1.  40 us is a good threshold between 0 and 1
  536.         if ((micros() - highStart) > ONE_THRESHOLD) {
  537.             buffer[i / BITS_PER_BYTE] |= (1 << bitIndex);
  538.         }
  539.  
  540.         // Decrement or reset bitIndex
  541.         bitIndex = (bitIndex > 0) ? bitIndex - 1 : BYTE_MS_BIT;
  542.     }
  543.  
  544.     // Check the checksum.  Only if it's good, record the new values.
  545.      if (buffer[CHECKSUM_INDEX] == (  buffer[0] + buffer[1]
  546.                                     + buffer[2] + buffer[3])) {
  547.         this->humidity    = buffer[HUMIDITY_INDEX];
  548.         this->temperatureC = buffer[TEMPERATURE_INDEX];
  549.         this->temperatureF = (this->temperatureC * 9.0)/ 5.0 + 32.0; ;
  550.     } else {
  551.         status = ERROR_CHECKSUM;
  552.     }
  553.  
  554. done:
  555.     return status;
  556. }
  557.  
  558. /*
  559.  -----------------------------------------------------------------------------
  560.                                 Analog Inputs
  561.  -----------------------------------------------------------------------------
  562.  */
  563.  
  564. /*      Potentiometer       */
  565.  
  566. Potentiometer::Potentiometer(uint8_t _pin) : AnalogInput(_pin)
  567.  
  568. {
  569.     pin = _pin;
  570.     _minVal = 1023;
  571.     _maxVal = 0;
  572. }
  573.  
  574. int Potentiometer::read()
  575. {
  576.  
  577.     int val = AnalogInput::read();
  578.  
  579.     if (val < _minVal) {_minVal = val;}
  580.     if (val > _maxVal) {_maxVal = val;}
  581.  
  582.     _mappedVal = map(val, _minVal, _maxVal, 0, 1023);
  583.     _mappedVal = constrain(_mappedVal, 0, 1023);
  584.  
  585.     return _mappedVal;
  586. }
  587.  
  588. int Potentiometer::readStep(int steps) {
  589.  
  590.     _steps = steps;
  591.  
  592.     int step  = floor(map(read(), 0, 1023, 0, _steps));
  593.  
  594.     return step;
  595. }
  596.  
  597.  
  598. /*      Light Sensor        */
  599.  
  600. LightSensor::LightSensor(uint8_t _pin) : AnalogInput(_pin){}
  601.  
  602. /*      Temperature Sensor       */
  603.  
  604. // Thermistor
  605. Thermistor::Thermistor(uint8_t _pin) : AnalogInput(_pin) {}
  606.  
  607. float Thermistor::readCelsius()
  608. {
  609.     float Rthermistor = Rb * (ADCres / Thermistor::read() - 1);
  610.     float _temperatureC = Beta / (log( Rthermistor * Ginf )) ;
  611.  
  612.     return _temperatureC - Kelvin;
  613. }
  614.  
  615. float Thermistor::readFahrenheit()
  616. {
  617.     float _temperatureF = (Thermistor::readCelsius() * 9.0)/ 5.0 + 32.0; ;
  618.  
  619.     return _temperatureF;
  620. }
  621.  
  622. // LM35
  623. LM35::LM35(uint8_t _pin) : AnalogInput(_pin) {}
  624.  
  625. float LM35::readCelsius()
  626. {
  627.     float _temperatureC = LM35::read() * 5 / ADCres / Acc ;
  628.  
  629.     return _temperatureC;
  630. }
  631.  
  632. float LM35::readFahrenheit()
  633. {
  634.     float _temperatureF = (LM35::readCelsius() * 9.0)/ 5.0 + 32.0; ;
  635.  
  636.     return _temperatureF;
  637. }
  638.  
  639. /*
  640. -----------------------------------------------------------------------------
  641.                                         Outputs
  642. -----------------------------------------------------------------------------
  643. */
  644.  
  645. /* LED */
  646.  
  647. Led::Led(uint8_t _pin) : Output(_pin) {}
  648.  
  649.  
  650. /* MosFet */
  651.  
  652. MosFet::MosFet(uint8_t _pin) : Output(_pin) {}
  653.  
  654.  
  655. /* Relay */
  656.  
  657. Relay::Relay(uint8_t _pin) : Output(_pin) {}
  658.  
  659. /* ServoMotor */
  660.  
  661. ServoMotor::ServoMotor(uint8_t _pin)
  662. {
  663.   Servo _servo;
  664.   _servo.attach(_pin);
  665. }
  666.  
  667. int ServoMotor::write(uint8_t _value)
  668. {
  669.   _servo.write(_value);
  670. }
  671.  
  672. /* Piezo */
  673.  
  674. Piezo::Piezo(uint8_t _pin) : Output(_pin) {}
  675.  
  676. void Piezo::beep(int _tone)
  677. {
  678.   if (_tone > SILENCE)
  679.     tone(pin, _tone);
  680. }
  681.  
  682. void Piezo::beep(int _tone, int _duration)
  683. {
  684.   if (_tone > SILENCE)
  685.     tone(pin, _tone, _duration);
  686. }
  687.  
  688. void Piezo::play(int melody[])
  689. {
  690.   //size_t n = sizeof(melody)/sizeof(melody[0]);
  691.   int n = getMelodySize(melody);
  692.   for (int i = 0; i < n; i+=2) {
  693.     // to calculate the note duration, take one second divided by the note type.
  694.     //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
  695.     int noteDuration = 1000 / melody[i+1];
  696.     beep(melody[i], noteDuration);
  697.  
  698.     // to distinguish the notes, set a minimum time between them.
  699.     // the note's duration + 30% seems to work well:
  700.     int pauseBetweenNotes = noteDuration * 1.30;
  701.     delay(pauseBetweenNotes);
  702.   }
  703.   noTone(pin);
  704. }
  705.  
  706. void Piezo::play(int n, int melody[])
  707. {
  708.   for (int i = 0; i < n; i+=2) {
  709.     // to calculate the note duration, take one second divided by the note type.
  710.     //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
  711.     int noteDuration = 1000 / melody[i+1];
  712.     beep(melody[i], noteDuration);
  713.  
  714.     // to distinguish the notes, set a minimum time between them.
  715.     // the note's duration + 30% seems to work well:
  716.     int pauseBetweenNotes = noteDuration * 1.30;
  717.     delay(pauseBetweenNotes);
  718.   }
  719.   noTone(pin);
  720. }
  721.  
  722. int Piezo::getMelodySize(int melody[])
  723. {
  724.   int count = 0;
  725.   while (melody[count] != NULL)
  726.     count++;
  727.   return count;
  728. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement