diff --git a/sketches/DHT_Simulator/.arduino-ci.yml b/sketches/DHT_Simulator/.arduino-ci.yml new file mode 100644 index 00000000..77a333f9 --- /dev/null +++ b/sketches/DHT_Simulator/.arduino-ci.yml @@ -0,0 +1,28 @@ +platforms: + rpipico: + board: rp2040:rp2040:rpipico + package: rp2040:rp2040 + gcc: + features: + defines: + - ARDUINO_ARCH_RP2040 + warnings: + flags: + +packages: + rp2040:rp2040: + url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json + +compile: + # Choosing to run compilation tests on 2 different Arduino platforms + platforms: + - uno + # - due + # - zero + # - leonardo + - m4 + - esp32 + - esp8266 + # - mega2560 + - rpipico + diff --git a/sketches/DHT_Simulator/.github/FUNDING.yml b/sketches/DHT_Simulator/.github/FUNDING.yml new file mode 100644 index 00000000..90d9ab4c --- /dev/null +++ b/sketches/DHT_Simulator/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: RobTillaart + diff --git a/sketches/DHT_Simulator/.github/workflows/arduino-lint.yml b/sketches/DHT_Simulator/.github/workflows/arduino-lint.yml new file mode 100644 index 00000000..b2ca058c --- /dev/null +++ b/sketches/DHT_Simulator/.github/workflows/arduino-lint.yml @@ -0,0 +1,13 @@ + +name: Arduino-lint + +on: [push, pull_request] +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: arduino/arduino-lint-action@v1 + with: + library-manager: update + compliance: strict diff --git a/sketches/DHT_Simulator/.github/workflows/arduino_test_runner.yml b/sketches/DHT_Simulator/.github/workflows/arduino_test_runner.yml new file mode 100644 index 00000000..096b975b --- /dev/null +++ b/sketches/DHT_Simulator/.github/workflows/arduino_test_runner.yml @@ -0,0 +1,17 @@ +--- +name: Arduino CI + +on: [push, pull_request] + +jobs: + runTest: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.6 + - run: | + gem install arduino_ci + arduino_ci.rb diff --git a/sketches/DHT_Simulator/.github/workflows/jsoncheck.yml b/sketches/DHT_Simulator/.github/workflows/jsoncheck.yml new file mode 100644 index 00000000..04603d08 --- /dev/null +++ b/sketches/DHT_Simulator/.github/workflows/jsoncheck.yml @@ -0,0 +1,18 @@ +name: JSON check + +on: + push: + paths: + - '**.json' + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: json-syntax-check + uses: limitusus/json-syntax-check@v1 + with: + pattern: "\\.json$" + diff --git a/sketches/DHT_Simulator/LICENSE b/sketches/DHT_Simulator/LICENSE index 0637a28b..4feba6f8 100644 --- a/sketches/DHT_Simulator/LICENSE +++ b/sketches/DHT_Simulator/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2014-2021 Rob Tillaart +Copyright (c) 2014-2022 Rob Tillaart Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/sketches/DHT_Simulator/README.md b/sketches/DHT_Simulator/README.md index c2ffae76..d10eb459 100644 --- a/sketches/DHT_Simulator/README.md +++ b/sketches/DHT_Simulator/README.md @@ -1,12 +1,16 @@ [![Arduino CI](https://github.com/RobTillaart/DHT_Simulator/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci) +[![Arduino-lint](https://github.com/RobTillaart/DHT_Simulator/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/DHT_Simulator/actions/workflows/arduino-lint.yml) +[![JSON check](https://github.com/RobTillaart/DHT_Simulator/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/DHT_Simulator/actions/workflows/jsoncheck.yml) [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/DHT_Simulator/blob/master/LICENSE) [![GitHub release](https://img.shields.io/github/release/RobTillaart/DHT_Simulator.svg?maxAge=3600)](https://github.com/RobTillaart/DHT_Simulator/releases) + # DHT_Simulator Arduino sketch to simulate a DHT22 temperature and humidity sensor. + ## Description The DHT22 is an often used sensor and many libraries are written for it @@ -17,15 +21,20 @@ I wrote a simulator for the DHT sensors in 2014. The simulator can be used to test applications to that use a DHT sensor, e.g. to get high alarm temp or whatever. -Currently the code uses two analog ports to get a value for temperature -and humidity. Just connect two potmeters to play and simulate increase and +Currently the code uses two analogue ports to get a value for temperature +and humidity. Just connect two potentiometers to play and simulate increase and decrease of the temperature and humidity. + +## 2022-11-01 +- add RP2040 to build-CI +- update license + ## 0.2.1 - added pin to trigger CRC errors - added temp and hum pin for input for CI -- added pins for CRC error, pulselength error and timeout error +- added pins for CRC error, pulse length error and timeout error (to be tested in detail) @@ -39,17 +48,19 @@ decrease of the temperature and humidity. The simulator is not tested extensively so please report bugs. + ## Future 1) use the simulator-core as a bridge to other sensors. Idea is to use the code of the simulator in combination with a -Senserion or two separate sensors (DS18B20 + ? ) to provide an +Sensirion or two separate sensors (DS18B20 + ? ) to provide an accurate temperature and humidity. These could then be readable with any DHT library with the performance of a DHT (~ 5ms). (when time permits) 2) implement a recorder mode, to be able to replay a certain -behavior time after time. +behaviour time after time. + ## Operation diff --git a/sketches/DHT_Simulator/examples/DHT_Simulator/DHT_Simulator.ino b/sketches/DHT_Simulator/examples/DHT_Simulator/DHT_Simulator.ino new file mode 100644 index 00000000..6dc96f51 --- /dev/null +++ b/sketches/DHT_Simulator/examples/DHT_Simulator/DHT_Simulator.ino @@ -0,0 +1,210 @@ +// +// FILE: DHT_simulator.ino +// AUTHOR: Rob Tillaart +// VERSION: 0.2.1 +// PURPOSE: Simulation of the DHT protocol +// DATE: 2014-06-14 +// URL: https://github.com/RobTillaart/DHT_Simulator + +// TODO +// - split loop into some functions? + + +// SET ACTUAL PINS PER PLATFORM +const int dataPin = 5; // connect to MCU ( !! also connect GND !! ) +const int CRCPin = 6; // connect switch to simulate CRC errors. +const int TimeOutPin = 7; // connect switch to simulate timeout errors. +const int PulseLenPin = 8; // connect switch to simulate pulselength errors. + + +#if defined(__AVR__) +const int humPin = A0; // analog pins for potmeters. +const int tempPin = A2; +#elif defined(ESP32) +const int humPin = 14; +const int tempPin = 15; +#elif defined(ESP8266) +const int humPin = 2; +const int tempPin = 3; +#else // CI +const int humPin = A0; +const int tempPin = A2; +#endif + + +// DATA TO SEND +byte b[5]; // actual bytes sent +int humidity; // humidity * 10 - prevent float operations +int temperature; // temperature * 10 + + +// CONFIGURE +const bool randomize = true; // use random generator +const bool debug = false; // test data generation + +bool CRCerror = false; // inject CRC error +bool TimeOutError = false; // +bool PulseLenError = false; //. +uint32_t count = 0; // count values per second generated +uint32_t lastTime = 0; // keep track of timing + + +///////////////////////////////////////// +void setup() +{ + Serial.begin(115200); + Serial.print("Start "); + Serial.println(__FILE__); + + pinMode(dataPin, INPUT_PULLUP); + pinMode(CRCPin, INPUT_PULLUP); + pinMode(TimeOutPin, INPUT_PULLUP); + pinMode(PulseLenPin, INPUT_PULLUP); +} + +void loop() +{ + yield(); // keep ESP happy + + count++; + uint32_t now = millis(); + if (now - lastTime >= 1000) + { + uint32_t nps = round((1000.0 * count) / (now - lastTime)); + Serial.print("DATA PER SECOND: "); + Serial.println(nps); + lastTime = now; + count = 0; + } + + if (randomize) + { + humidity = random(20, 1000); + temperature = random(-200, 1800); + } + else + { + analogRead(humPin); + humidity = analogRead(humPin); + analogRead(tempPin); + temperature = analogRead(tempPin) * 2 - 200; + } + humidity = constrain(humidity, 0, 1000); + temperature = constrain(temperature, -200, 1800); + + if (debug) + { + Serial.print(humidity); + Serial.print("\t"); + Serial.print(temperature); + Serial.println(); + } + + + // READ "ERROR" PINS + CRCerror = digitalRead(CRCPin) == LOW; + TimeOutError = digitalRead(TimeOutPin) == LOW; + PulseLenError = digitalRead(PulseLenPin) == LOW; + + + // WAKE UP SIGNAL DETECTED + if (digitalRead(dataPin) == LOW) + { + uint32_t start = micros(); + // wait max 1500 us until signal goes high + while (digitalRead(dataPin) == LOW) + { + if (micros() - start > 1500) + { + // Serial.println("ERROR: low puise too long"); + return; + } + } + if (micros() - start > 500) // serious request... + { + DHTsend(humidity, temperature); + + Serial.print(humidity); + Serial.print("\t"); + Serial.print(temperature); + Serial.print("\t"); + for (int i = 0; i < 5; i++) + { + if (b[i] < 0x10) Serial.print('0'); + Serial.print(b[i], HEX); + Serial.print(' '); + } + Serial.println(); + } + else + { + Serial.println("ERROR: low puise too short"); + } + } +} + + +void DHTsend(int H, int T) +{ + pinMode(dataPin, OUTPUT); + // SEND ACK + digitalWrite(dataPin, LOW); + delayMicroseconds(80); // 80 us + digitalWrite(dataPin, HIGH); + delayMicroseconds(80); // 80 us + + if (TimeOutError) + { + delayMicroseconds(100); // inject extra 100 microseconds + } + + // PREPARE DATA + b[0] = H / 256; + b[1] = H & 255; + + b[2] = 0; + if (T < 0) + { + T = -T; + b[2] = 0x80; + } + + b[2] |= T / 256; + b[3] = T & 255; + + // CRC + b[4] = b[0] + b[1] + b[2] + b[3]; + if (CRCerror) b[4]++; // inject CRC error + + // SEND DATA + for (int i = 0; i < 5; i++) + { + DHTsendbyte(b[i]); + } + + // END OF TRANSMISSION SIGNAL + digitalWrite(dataPin, LOW); + delayMicroseconds(50); // 50 us + pinMode(dataPin, INPUT_PULLUP); +} + +// timing manual tuned +void DHTsendbyte(byte b) +{ + byte mask = 128; + for (int i = 0; i < 8; i++) + { + digitalWrite(dataPin, LOW); + delayMicroseconds(45); // 50 us + if (PulseLenError) + { + delayMicroseconds(10); // inject extra pulselength // TWEAK amount + } + digitalWrite(dataPin, HIGH); + if (b & mask) delayMicroseconds(60); // 70 us + else delayMicroseconds(24); // 26 us + mask >>= 1; + } +} + +// -- END OF FILE -- diff --git a/sketches/DHT_Simulator/examples/DHT_Simulator/readme.txt b/sketches/DHT_Simulator/examples/DHT_Simulator/readme.txt new file mode 100644 index 00000000..da5f8748 --- /dev/null +++ b/sketches/DHT_Simulator/examples/DHT_Simulator/readme.txt @@ -0,0 +1,8 @@ + +2020-12-19 + +This is a copy of the .ino file from the root folder. +It is placed here so Arduino-CI will compile it. + +TODO - check if github can work with symbolic links. + diff --git a/sketches/DHT_Simulator/test/unit_test_001.cpp_no_test b/sketches/DHT_Simulator/test/unit_test_001.cpp_no_test new file mode 100644 index 00000000..b4d762fa --- /dev/null +++ b/sketches/DHT_Simulator/test/unit_test_001.cpp_no_test @@ -0,0 +1,47 @@ +// +// FILE: unit_test_001.cpp +// AUTHOR: Rob Tillaart +// DATE: 2020-12-19 +// PURPOSE: unit tests for the DHT Simulator +// https://github.com/RobTillaart/ +// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md +// + +// supported assertions +// ---------------------------- +// assertEqual(expected, actual) +// assertNotEqual(expected, actual) +// assertLess(expected, actual) +// assertMore(expected, actual) +// assertLessOrEqual(expected, actual) +// assertMoreOrEqual(expected, actual) +// assertTrue(actual) +// assertFalse(actual) +// assertNull(actual) + +#include + +// Develop a DHT simultor class? +// or more generic a simulator class? + + +#include "Arduino.h" +// #include "XXXXX.h" + + +unittest_setup() +{ +} + +unittest_teardown() +{ +} + +unittest(test_constructor) +{ + assertEqual(1, 1); +} + +unittest_main() + +// --------