Defend
7 years ago
commit
48d3016d1d
11 changed files with 1111 additions and 0 deletions
@ -0,0 +1,3 @@ |
|||||
|
.pioenvs |
||||
|
.piolibdeps |
||||
|
.vscode/c_cpp_properties.json |
@ -0,0 +1,65 @@ |
|||||
|
# Continuous Integration (CI) is the practice, in software |
||||
|
# engineering, of merging all developer working copies with a shared mainline |
||||
|
# several times a day < http://docs.platformio.org/page/ci/index.html > |
||||
|
# |
||||
|
# Documentation: |
||||
|
# |
||||
|
# * Travis CI Embedded Builds with PlatformIO |
||||
|
# < https://docs.travis-ci.com/user/integration/platformio/ > |
||||
|
# |
||||
|
# * PlatformIO integration with Travis CI |
||||
|
# < http://docs.platformio.org/page/ci/travis.html > |
||||
|
# |
||||
|
# * User Guide for `platformio ci` command |
||||
|
# < http://docs.platformio.org/page/userguide/cmd_ci.html > |
||||
|
# |
||||
|
# |
||||
|
# Please choice one of the following templates (proposed below) and uncomment |
||||
|
# it (remove "# " before each line) or use own configuration according to the |
||||
|
# Travis CI documentation (see above). |
||||
|
# |
||||
|
|
||||
|
|
||||
|
# |
||||
|
# Template #1: General project. Test it using existing `platformio.ini`. |
||||
|
# |
||||
|
|
||||
|
# language: python |
||||
|
# python: |
||||
|
# - "2.7" |
||||
|
# |
||||
|
# sudo: false |
||||
|
# cache: |
||||
|
# directories: |
||||
|
# - "~/.platformio" |
||||
|
# |
||||
|
# install: |
||||
|
# - pip install -U platformio |
||||
|
# |
||||
|
# script: |
||||
|
# - platformio run |
||||
|
|
||||
|
|
||||
|
# |
||||
|
# Template #2: The project is intended to by used as a library with examples |
||||
|
# |
||||
|
|
||||
|
# language: python |
||||
|
# python: |
||||
|
# - "2.7" |
||||
|
# |
||||
|
# sudo: false |
||||
|
# cache: |
||||
|
# directories: |
||||
|
# - "~/.platformio" |
||||
|
# |
||||
|
# env: |
||||
|
# - PLATFORMIO_CI_SRC=path/to/test/file.c |
||||
|
# - PLATFORMIO_CI_SRC=examples/file.ino |
||||
|
# - PLATFORMIO_CI_SRC=path/to/test/directory |
||||
|
# |
||||
|
# install: |
||||
|
# - pip install -U platformio |
||||
|
# |
||||
|
# script: |
||||
|
# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N |
@ -0,0 +1,14 @@ |
|||||
|
{ |
||||
|
"version": "0.2.0", |
||||
|
"configurations": [ |
||||
|
{ |
||||
|
"type": "gdb", |
||||
|
"request": "launch", |
||||
|
"cwd": "${workspaceRoot}", |
||||
|
"name": "PlatformIO Debugger", |
||||
|
"target": "c:/Users/itsmy_000/Desktop/node_mcu_001/.pioenvs/nodemcuv2/firmware.elf", |
||||
|
"gdbpath": "C:/Users/itsmy_000/.platformio/penv/Scripts/piodebuggdb", |
||||
|
"autorun": [ "source .pioinit" ] |
||||
|
} |
||||
|
] |
||||
|
} |
@ -0,0 +1,65 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html> |
||||
|
<style> |
||||
|
button { |
||||
|
width: 190px; |
||||
|
height: 40px; |
||||
|
} |
||||
|
|
||||
|
#navs { |
||||
|
height: 40px; |
||||
|
width: 400px; |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
footer { |
||||
|
height: 5%; |
||||
|
text-align: center; |
||||
|
width: 100%; |
||||
|
margin-top: 100px; |
||||
|
} |
||||
|
|
||||
|
.clear { |
||||
|
clear: left; |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
<body> |
||||
|
<div id="main_block" align="center"> |
||||
|
<h2>Лабораторная работа *НАЗВАНИЕ*</h2> |
||||
|
<h3>Акселерометр ADW22035Z - Cемейство ADXL103</h3> |
||||
|
<p>Акселерометр подает на выход данные по одной оси. |
||||
|
<br />Частота обновления графика - 1 раз в двадцать секунд. |
||||
|
<br />Данные с сенсора снимаются с частотой в 20Hz. </p> |
||||
|
|
||||
|
<canvas id="myCanvas" width="400" height="200" style="border:1px solid #3c70ff;"> |
||||
|
Браузер устарел! |
||||
|
</canvas> |
||||
|
|
||||
|
<script> |
||||
|
var c = document.getElementById("myCanvas"); |
||||
|
var context = c.getContext("2d"); |
||||
|
var randomNumbers, randNumsLength; |
||||
|
context.moveTo(0, 0); |
||||
|
for (i = 0; i != 400; i+=4) { |
||||
|
context.lineTo(i, Math.random() * 100 + 50); |
||||
|
} |
||||
|
context.stroke(); |
||||
|
context.font = "50px Arial"; |
||||
|
context.fillText("24",320,170); |
||||
|
</script> |
||||
|
|
||||
|
<div id="navs"> |
||||
|
<button onclick="window.location.href='/hbs.html'"class="button">Оптодатчик</button> |
||||
|
</div> |
||||
|
<div class="clear"></div> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<footer> |
||||
|
Тамбовский Государственный Технический Университет 2017 г. |
||||
|
</footer> |
||||
|
|
||||
|
</body> |
||||
|
|
||||
|
</html> |
@ -0,0 +1,73 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html> |
||||
|
<style> |
||||
|
button { |
||||
|
width: 190px; |
||||
|
height: 40px; |
||||
|
} |
||||
|
|
||||
|
#navs { |
||||
|
height: 40px; |
||||
|
width: 400px; |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
footer { |
||||
|
height: 5%; |
||||
|
text-align: center; |
||||
|
width: 100%; |
||||
|
margin-top: 100px; |
||||
|
} |
||||
|
|
||||
|
.clear { |
||||
|
clear: left; |
||||
|
} |
||||
|
|
||||
|
#hbs_text { |
||||
|
text-align: left; |
||||
|
width: 400px; |
||||
|
text-indent: 20px; |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
<body> |
||||
|
<div id="main_block" align="center"> |
||||
|
<h2>Лабораторная работа *НАЗВАНИЕ*</h2> |
||||
|
<h3>Высокочувствительный оптодатчик ADPD2214</h3> |
||||
|
<p id="hbs_text">Применяется для измерения пульса, расчета фотоплетизмограммы. Низкое энергопотребление, а также управляемое выключение |
||||
|
этого электроприбора позволяет использовать его в портативных устройствах. |
||||
|
</p> |
||||
|
<p id="hbs_text">Также применяется в химическом анализе. Частота обновления графика - 1 раз в двадцать секунд. Данные с сенсора снимаются |
||||
|
с частотой в 20Hz. </p> |
||||
|
|
||||
|
<canvas id="myCanvas" width="400" height="200" style="border:1px solid #3c70ff;"> |
||||
|
Браузер устарел! |
||||
|
</canvas> |
||||
|
|
||||
|
<script> |
||||
|
var c = document.getElementById("myCanvas"); |
||||
|
var context = c.getContext("2d"); |
||||
|
var randomNumbers, randNumsLength; |
||||
|
context.moveTo(0, 0); |
||||
|
for (i = 0; i != 400; i += 4) { |
||||
|
context.lineTo(i, Math.random() * 100 + 50); |
||||
|
} |
||||
|
context.stroke(); |
||||
|
context.font = "50px Arial"; |
||||
|
context.fillText("122",300,170); |
||||
|
</script> |
||||
|
|
||||
|
<div id="navs"> |
||||
|
<button onclick="window.location.href='/acc.html?f=0'" class="button">Акселерометр</button> |
||||
|
</div> |
||||
|
<div class="clear"></div> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<footer> |
||||
|
Тамбовский Государственный Технический Университет 2017 г. |
||||
|
</footer> |
||||
|
|
||||
|
</body> |
||||
|
|
||||
|
</html> |
@ -0,0 +1,36 @@ |
|||||
|
|
||||
|
This directory is intended for the project specific (private) libraries. |
||||
|
PlatformIO will compile them to static libraries and link to executable file. |
||||
|
|
||||
|
The source code of each library should be placed in separate directory, like |
||||
|
"lib/private_lib/[here are source files]". |
||||
|
|
||||
|
For example, see how can be organized `Foo` and `Bar` libraries: |
||||
|
|
||||
|
|--lib |
||||
|
| |--Bar |
||||
|
| | |--docs |
||||
|
| | |--examples |
||||
|
| | |--src |
||||
|
| | |- Bar.c |
||||
|
| | |- Bar.h |
||||
|
| |--Foo |
||||
|
| | |- Foo.c |
||||
|
| | |- Foo.h |
||||
|
| |- readme.txt --> THIS FILE |
||||
|
|- platformio.ini |
||||
|
|--src |
||||
|
|- main.c |
||||
|
|
||||
|
Then in `src/main.c` you should use: |
||||
|
|
||||
|
#include <Foo.h> |
||||
|
#include <Bar.h> |
||||
|
|
||||
|
// rest H/C/CPP code |
||||
|
|
||||
|
PlatformIO will find your libraries automatically, configure preprocessor's |
||||
|
include paths and build them. |
||||
|
|
||||
|
More information about PlatformIO Library Dependency Finder |
||||
|
- http://docs.platformio.org/page/librarymanager/ldf.html |
@ -0,0 +1,15 @@ |
|||||
|
; PlatformIO Project Configuration File |
||||
|
; |
||||
|
; Build options: build flags, source filter |
||||
|
; Upload options: custom upload port, speed and extra flags |
||||
|
; Library options: dependencies, extra library storages |
||||
|
; Advanced options: extra scripting |
||||
|
; |
||||
|
; Please visit documentation for the other options and examples |
||||
|
; http://docs.platformio.org/page/projectconf.html |
||||
|
|
||||
|
[env:nodemcuv2] |
||||
|
platform = espressif8266 |
||||
|
board = nodemcuv2 |
||||
|
framework = arduino |
||||
|
monitor_baud = 115200 |
@ -0,0 +1,428 @@ |
|||||
|
/* DHT12 library
|
||||
|
|
||||
|
MIT license |
||||
|
written by Renzo Mischianti |
||||
|
*/ |
||||
|
|
||||
|
#include "DHT12.h" |
||||
|
#include "Wire.h" |
||||
|
|
||||
|
// Default is i2c on default pin with default DHT12 adress
|
||||
|
DHT12::DHT12(void) { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
DHT12::DHT12(uint8_t addressOrPin, bool oneWire) { |
||||
|
_isOneWire = oneWire; |
||||
|
if (oneWire) { |
||||
|
_pin = addressOrPin; |
||||
|
#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
|
||||
|
// basd on the speed of the processor.
|
||||
|
|
||||
|
DEBUG_PRINTLN("PIN MODE"); |
||||
|
} else { |
||||
|
_address = addressOrPin; |
||||
|
DEBUG_PRINTLN("I2C MODE"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Is not good idea use other pin for i2c as standard on Arduino you can get lag.
|
||||
|
// The lag happens when you choose "different pins", because you are then using a
|
||||
|
// slow software emulation of the I2C hardware. The built in I2C hardware has fixed pin assignments.
|
||||
|
#ifndef __AVR |
||||
|
DHT12::DHT12(uint8_t sda, uint8_t scl) { |
||||
|
_isOneWire = false; |
||||
|
_sda = sda; |
||||
|
_scl = scl; |
||||
|
} |
||||
|
|
||||
|
DHT12::DHT12(uint8_t sda, uint8_t scl, uint8_t address) { |
||||
|
_isOneWire = false; |
||||
|
_sda = sda; |
||||
|
_scl = scl; |
||||
|
_address = address; |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
void DHT12::begin() { |
||||
|
_lastreadtime = -(MIN_ELAPSED_TIME + 1); |
||||
|
if (_isOneWire) { |
||||
|
// 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.
|
||||
|
DEBUG_PRINT("Max clock cycles: "); |
||||
|
DEBUG_PRINTLN(_maxcycles, DEC); |
||||
|
} else { |
||||
|
#ifndef __AVR |
||||
|
Wire.begin(_sda, _scl); |
||||
|
#else |
||||
|
// Default pin for AVR some problem on software emulation
|
||||
|
// #define SCL_PIN _scl
|
||||
|
// #define SDA_PIN _sda
|
||||
|
Wire.begin(); |
||||
|
#endif |
||||
|
DEBUG_PRINT("I2C Inizialization: sda, scl: "); |
||||
|
DEBUG_PRINT(_sda); |
||||
|
DEBUG_PRINT(","); |
||||
|
DEBUG_PRINTLN(_scl); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
DHT12::ReadStatus DHT12::readStatus(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_ELAPSED_TIME)) { |
||||
|
return _lastresult; // return last correct measurement
|
||||
|
} |
||||
|
_lastreadtime = currenttime; |
||||
|
|
||||
|
if (_isOneWire) { |
||||
|
// Reset 40 bits of received data to zero.
|
||||
|
data[0] = data[1] = data[2] = data[3] = data[4] = 0; |
||||
|
|
||||
|
// 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.
|
||||
|
digitalWrite(_pin, HIGH); |
||||
|
delay(250); |
||||
|
|
||||
|
// First set data line low for 20 milliseconds.
|
||||
|
pinMode(_pin, OUTPUT); |
||||
|
digitalWrite(_pin, LOW); |
||||
|
delay(20); |
||||
|
|
||||
|
uint32_t cycles[80]; |
||||
|
{ |
||||
|
// Turn off interrupts temporarily because the next sections are timing critical
|
||||
|
// and we don't want any interruptions.
|
||||
|
InterruptLock lock; |
||||
|
|
||||
|
// End the start signal by setting data line high for 40 microseconds.
|
||||
|
digitalWrite(_pin, HIGH); |
||||
|
delayMicroseconds(40); |
||||
|
|
||||
|
// Now start reading the data line to get the value from the DHT sensor.
|
||||
|
pinMode(_pin, INPUT_PULLUP); |
||||
|
delayMicroseconds(10); // Delay a bit to let sensor pull data line low.
|
||||
|
|
||||
|
// First expect a low signal for ~80 microseconds followed by a high signal
|
||||
|
// for ~80 microseconds again.
|
||||
|
if (expectPulse(LOW) == 0) { |
||||
|
DEBUG_PRINTLN(F("Timeout waiting for start signal low pulse.")); |
||||
|
_lastresult = ERROR_TIMEOUT_LOW; |
||||
|
return _lastresult; |
||||
|
} |
||||
|
if (expectPulse(HIGH) == 0) { |
||||
|
DEBUG_PRINTLN(F("Timeout waiting for start signal high pulse.")); |
||||
|
_lastresult = ERROR_TIMEOUT_HIGH; |
||||
|
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[i + 1] = expectPulse(HIGH); |
||||
|
} |
||||
|
|
||||
|
// 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 == 0) || (highCycles == 0)) { |
||||
|
DEBUG_PRINTLN(F("Timeout waiting for pulse.")); |
||||
|
_lastresult = ERROR_TIMEOUT; |
||||
|
return _lastresult; |
||||
|
} |
||||
|
data[i/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[i/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:")); |
||||
|
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); |
||||
|
|
||||
|
DHT12::ReadStatus cks = DHT12::_checksum(); |
||||
|
if (cks != OK) { |
||||
|
DEBUG_PRINTLN("CHECKSUM ERROR!"); |
||||
|
_lastresult = cks; |
||||
|
return cks; |
||||
|
} |
||||
|
|
||||
|
_lastresult = OK; |
||||
|
return OK; |
||||
|
} |
||||
|
// return DHT12::_readSensor(DHTLIB_DHT_WAKEUP, DHTLIB_DHT_LEADING_ZEROS);
|
||||
|
// return DHT12::_readSensor(DHTLIB_DHT11_WAKEUP, DHTLIB_DHT11_LEADING_ZEROS);
|
||||
|
|
||||
|
} else { |
||||
|
DEBUG_PRINT("I2C START READING.."); |
||||
|
Wire.beginTransmission(_address); |
||||
|
Wire.write(0); |
||||
|
if (Wire.endTransmission() != 0) { |
||||
|
DEBUG_PRINTLN("CONNECTION ERROR!"); |
||||
|
_lastresult = ERROR_CONNECT; |
||||
|
return _lastresult; |
||||
|
} |
||||
|
Wire.requestFrom(_address, (uint8_t) 5); |
||||
|
for (uint8_t i = 0; i < 5; ++i) { |
||||
|
data[i] = Wire.read(); |
||||
|
DEBUG_PRINTLN(data[i]); |
||||
|
} |
||||
|
|
||||
|
delay(1); |
||||
|
if (Wire.available() != 0) { |
||||
|
DEBUG_PRINTLN("TIMEOUT ERROR!"); |
||||
|
_lastresult = ERROR_TIMEOUT; |
||||
|
return _lastresult; |
||||
|
} |
||||
|
|
||||
|
DHT12::ReadStatus cks = DHT12::_checksum(); |
||||
|
if (cks != OK) { |
||||
|
DEBUG_PRINTLN("CHECKSUM ERROR!"); |
||||
|
_lastresult = cks; |
||||
|
return cks; |
||||
|
} |
||||
|
|
||||
|
DEBUG_PRINTLN("...READING OK"); |
||||
|
_lastresult = OK; |
||||
|
return _lastresult; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
bool DHT12::read(bool force) { |
||||
|
ReadStatus chk = DHT12::readStatus(force); |
||||
|
DEBUG_PRINT(F("\nRead sensor: ")); |
||||
|
DEBUG_PRINT((chk != DHT12::OK)); |
||||
|
switch (chk) { |
||||
|
case DHT12::OK: |
||||
|
DEBUG_PRINTLN(F("OK")); |
||||
|
break; |
||||
|
case DHT12::ERROR_CHECKSUM: |
||||
|
DEBUG_PRINTLN(F("Checksum error")) |
||||
|
; |
||||
|
break; |
||||
|
case DHT12::ERROR_TIMEOUT: |
||||
|
DEBUG_PRINTLN(F("Timeout error")) |
||||
|
; |
||||
|
break; |
||||
|
case DHT12::ERROR_TIMEOUT_HIGH: |
||||
|
DEBUG_PRINTLN(F("Timeout error high")) |
||||
|
; |
||||
|
break; |
||||
|
case DHT12::ERROR_TIMEOUT_LOW: |
||||
|
DEBUG_PRINTLN(F("Timeout error low")) |
||||
|
; |
||||
|
break; |
||||
|
case DHT12::ERROR_CONNECT: |
||||
|
DEBUG_PRINTLN(F("Connect error")) |
||||
|
; |
||||
|
break; |
||||
|
case DHT12::ERROR_ACK_L: |
||||
|
DEBUG_PRINTLN(F("AckL error")) |
||||
|
; |
||||
|
break; |
||||
|
case DHT12::ERROR_ACK_H: |
||||
|
DEBUG_PRINTLN(F("AckH error")) |
||||
|
; |
||||
|
break; |
||||
|
case DHT12::ERROR_UNKNOWN: |
||||
|
DEBUG_PRINTLN(F("Unknown error DETECTED")) |
||||
|
; |
||||
|
break; |
||||
|
case DHT12::NONE: |
||||
|
DEBUG_PRINTLN(F("No result")) |
||||
|
; |
||||
|
break; |
||||
|
default: |
||||
|
DEBUG_PRINTLN(F("Unknown error")) |
||||
|
; |
||||
|
break; |
||||
|
} |
||||
|
return (chk == DHT12::OK); |
||||
|
} |
||||
|
|
||||
|
float DHT12::convertCtoF(float c) { |
||||
|
return c * 1.8 + 32; |
||||
|
} |
||||
|
|
||||
|
float DHT12::convertFtoC(float f) { |
||||
|
return (f - 32) * 0.55555; |
||||
|
} |
||||
|
|
||||
|
//boolean isFahrenheit: True == Fahrenheit; False == Celcius
|
||||
|
float DHT12::computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit) { |
||||
|
// Using both Rothfusz and Steadman's equations
|
||||
|
// http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
|
||||
|
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); |
||||
|
} |
||||
|
|
||||
|
float DHT12::readHumidity(bool force) { |
||||
|
DEBUG_PRINTLN("----------------------------"); |
||||
|
float humidity = NAN; |
||||
|
|
||||
|
if (_isOneWire) { |
||||
|
if (DHT12::read(force)) { |
||||
|
DEBUG_PRINT(data[0]); |
||||
|
humidity = data[0]; |
||||
|
} |
||||
|
} else { |
||||
|
if (DHT12::read(force)) { |
||||
|
humidity = (data[0] + (float) data[1] / 10); |
||||
|
} |
||||
|
} |
||||
|
return humidity; |
||||
|
} |
||||
|
|
||||
|
//boolean S == Scale. True == Fahrenheit; False == Celcius
|
||||
|
float DHT12::readTemperature(bool scale, bool force) { |
||||
|
float temperature = NAN; |
||||
|
if (_isOneWire) { |
||||
|
if (DHT12::read(force)) { |
||||
|
temperature = data[2]; |
||||
|
if (scale) { |
||||
|
temperature = convertCtoF(temperature); |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
|
||||
|
bool r = DHT12::read(force); |
||||
|
DEBUG_PRINT("READ ---> "); |
||||
|
DEBUG_PRINTLN(r); |
||||
|
if (r) { |
||||
|
temperature = (data[2] + (float) data[3] / 10); //((data[2] & 0x7F)*256 + data[3]);
|
||||
|
// if (data[2] & 0x80) // negative temperature
|
||||
|
// temperature = -temperature;
|
||||
|
|
||||
|
if (scale) { |
||||
|
temperature = convertCtoF(temperature); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return temperature; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#include <math.h> |
||||
|
// dewPoint function NOAA
|
||||
|
// reference (1) : http://wahiduddin.net/calc/density_algorithms.htm
|
||||
|
// reference (2) : http://www.colorado.edu/geography/weather_station/Geog_site/about.htm
|
||||
|
//
|
||||
|
//boolean S == Scale. True == Fahrenheit; False == Celcius
|
||||
|
float DHT12::dewPoint(float temperature, float humidity, bool isFahrenheit) { |
||||
|
// sloppy but good approximation for 0 ... +70 °C with max. deviation less than 0.25 °C
|
||||
|
|
||||
|
float temp; |
||||
|
|
||||
|
if(!isFahrenheit){ |
||||
|
temp = temperature; |
||||
|
} else { |
||||
|
temp = convertFtoC(temperature); |
||||
|
} |
||||
|
|
||||
|
float humi = humidity; |
||||
|
float ans = (temp - (14.55 + 0.114 * temp) * (1 - (0.01 * humi)) - pow(((2.5 + 0.007 * temp) * (1 - (0.01 * humi))),3) - (15.9 + 0.117 * temp) * pow((1 - (0.01 * humi)), 14)); |
||||
|
|
||||
|
if(!isFahrenheit){ |
||||
|
return ans; // returns dew Point in Celsius
|
||||
|
} |
||||
|
|
||||
|
return convertCtoF(ans); // returns dew Point in Fahrenheit
|
||||
|
} |
||||
|
|
||||
|
//////// PRIVATE
|
||||
|
DHT12::ReadStatus DHT12::_checksum() { |
||||
|
uint8_t sum = data[0] + data[1] + data[2] + data[3]; |
||||
|
if (data[4] != sum) |
||||
|
return ERROR_CHECKSUM; |
||||
|
return OK; |
||||
|
} |
||||
|
|
||||
|
// 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 DHT12::expectPulse(bool level) { |
||||
|
uint32_t count = 0; |
||||
|
// 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 0; // 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 0; // Exceeded timeout, fail.
|
||||
|
} |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
return count; |
||||
|
} |
@ -0,0 +1,172 @@ |
|||||
|
/** \mainpage DHT12 sensor library
|
||||
|
* |
||||
|
* MIT license |
||||
|
* written by Renzo Mischianti |
||||
|
*/ |
||||
|
|
||||
|
#ifndef DHT12_h |
||||
|
#define DHT12_h |
||||
|
|
||||
|
#if ARDUINO >= 100 |
||||
|
#include "Arduino.h" |
||||
|
#else |
||||
|
#include "WProgram.h" |
||||
|
#endif |
||||
|
#include "Wire.h" |
||||
|
|
||||
|
#define DEFAULT_DHT12_ADDRESS 0x5C; |
||||
|
#define DEFAULT_SDA SDA; |
||||
|
#define DEFAULT_SCL SCL; |
||||
|
|
||||
|
#define MIN_ELAPSED_TIME 2000 |
||||
|
|
||||
|
// Uncomment to enable printing out nice debug messages.
|
||||
|
//#define DHT_DEBUG
|
||||
|
|
||||
|
// Define where debug output will be printed.
|
||||
|
#define DEBUG_PRINTER Serial |
||||
|
|
||||
|
// 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(...) {} |
||||
|
#define DEBUG_PRINTLN(...) {} |
||||
|
#endif |
||||
|
|
||||
|
#ifndef __AVR |
||||
|
#define DHTLIB_TIMEOUT 10000 // should be approx. clock/40000
|
||||
|
#else |
||||
|
#ifndef F_CPU |
||||
|
#define DHTLIB_TIMEOUT 1000 // should be approx. clock/40000
|
||||
|
#else |
||||
|
#define DHTLIB_TIMEOUT (F_CPU/40000) |
||||
|
#endif |
||||
|
#endif |
||||
|
|
||||
|
class DHT12 { |
||||
|
public: |
||||
|
/**Status of the read*/ |
||||
|
enum ReadStatus { |
||||
|
OK, /**All ok*/ |
||||
|
ERROR_CHECKSUM, /**Error on checksum*/ |
||||
|
ERROR_TIMEOUT, /**Timeout error*/ |
||||
|
ERROR_TIMEOUT_LOW, /**Timeout on wait after low pulse*/ |
||||
|
ERROR_TIMEOUT_HIGH,/**Timeout on wait after high pulse*/ |
||||
|
ERROR_CONNECT, /**Connection error (Wire)*/ |
||||
|
ERROR_ACK_L,/**Acknowledge Low */ |
||||
|
ERROR_ACK_H,/**Acknowledge High */ |
||||
|
ERROR_UNKNOWN, /**Error unknown */ |
||||
|
NONE |
||||
|
}; |
||||
|
|
||||
|
/**
|
||||
|
* Standard constructor, default wire connection on default SDA SCL pin |
||||
|
*/ |
||||
|
DHT12(void); |
||||
|
/**
|
||||
|
* Constructor |
||||
|
* @param addressORPin If oneWire == true this is pin number if oneWire false this is address of i2c |
||||
|
* @param oneWire select if is oneWire of i2c |
||||
|
*/ |
||||
|
DHT12(uint8_t addressORPin, bool oneWire = false); |
||||
|
#ifndef __AVR |
||||
|
/**
|
||||
|
* Additional parameter non tested for Arduino, Arduino very slow on software i2c |
||||
|
*/ |
||||
|
DHT12(uint8_t sda, uint8_t scl); |
||||
|
DHT12(uint8_t sda, uint8_t scl, uint8_t address); |
||||
|
#endif |
||||
|
/**
|
||||
|
* Start handshake |
||||
|
*/ |
||||
|
void begin(void); |
||||
|
/**
|
||||
|
* Read temperature |
||||
|
* @param scale Select false --> Celsius true --> Fahrenheit |
||||
|
* @param force |
||||
|
* @return |
||||
|
*/ |
||||
|
float readTemperature(bool scale = false, bool force = false); |
||||
|
/**
|
||||
|
* Convert Celsius to Fahrenheit |
||||
|
* @param |
||||
|
* @return |
||||
|
*/ |
||||
|
float convertCtoF(float); |
||||
|
/**
|
||||
|
* Convert Fahrenheit to Celsius |
||||
|
* @param |
||||
|
* @return |
||||
|
*/ |
||||
|
float convertFtoC(float); |
||||
|
/**
|
||||
|
* The heat index (HI) or humiture is an index that combines air temperature and relative humidity, in shaded areas, as an attempt to determine the human-perceived equivalent temperature, as how hot it would feel if the humidity were some other value in the shade. The result is also known as the "felt air temperature" or "apparent temperature". |
||||
|
* @param temperature |
||||
|
* @param percentHumidity |
||||
|
* @param isFahrenheit specify scale of temperature |
||||
|
* @return |
||||
|
*/ |
||||
|
float computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit = true); |
||||
|
/**
|
||||
|
* Read humidity percentage |
||||
|
* @param force Force to request new data (if 2secs is not passed from previous request) |
||||
|
* @return |
||||
|
*/ |
||||
|
float readHumidity(bool force = false); |
||||
|
/**
|
||||
|
* Dew point the atmospheric temperature (varying according to pressure and humidity) below which water droplets begin to condense and dew can form. |
||||
|
* @param temperature |
||||
|
* @param humidity |
||||
|
* @param isFahrenheit specify scale of temperature |
||||
|
* @return |
||||
|
*/ |
||||
|
float dewPoint(float temperature, float humidity, bool isFahrenheit = true); |
||||
|
/**
|
||||
|
* Read and return status of the read |
||||
|
* @param force |
||||
|
* @return |
||||
|
*/ |
||||
|
ReadStatus readStatus(bool force = false);bool read(bool force = false); |
||||
|
|
||||
|
private: |
||||
|
bool _isOneWire = false; |
||||
|
|
||||
|
uint8_t data[5]; |
||||
|
uint8_t _address = DEFAULT_DHT12_ADDRESS |
||||
|
; |
||||
|
uint8_t _sda = DEFAULT_SDA |
||||
|
; |
||||
|
uint8_t _scl = DEFAULT_SCL |
||||
|
; |
||||
|
|
||||
|
uint32_t _lastreadtime = 0; |
||||
|
ReadStatus _lastresult = NONE; |
||||
|
|
||||
|
uint8_t _pin = 3; |
||||
|
#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 = 0, _port = 0; |
||||
|
#endif |
||||
|
uint32_t _maxcycles = 0; |
||||
|
|
||||
|
ReadStatus _checksum(void); |
||||
|
uint32_t expectPulse(bool level); |
||||
|
ReadStatus _readSensor(uint8_t wakeupDelay, uint8_t leadingZeroBits); |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
class InterruptLock { |
||||
|
public: |
||||
|
InterruptLock() { |
||||
|
noInterrupts(); |
||||
|
} |
||||
|
~InterruptLock() { |
||||
|
interrupts(); |
||||
|
} |
||||
|
|
||||
|
}; |
||||
|
|
||||
|
#endif |
@ -0,0 +1,120 @@ |
|||||
|
#include <Arduino.h> |
||||
|
|
||||
|
enum parts |
||||
|
{ |
||||
|
HTML_BEGIN, |
||||
|
HTML_END, |
||||
|
STYLE, |
||||
|
SCRIPT_BEGIN, |
||||
|
SCRIPT_END |
||||
|
}; |
||||
|
|
||||
|
const char html_begin[] PROGMEM = { |
||||
|
"<!DOCTYPE html>\
|
||||
|
<html>"}; |
||||
|
|
||||
|
const char style[] PROGMEM = { |
||||
|
"<head>\
|
||||
|
<style>\ |
||||
|
button {\ |
||||
|
width: 190px;\ |
||||
|
height: 40px;\ |
||||
|
}\ |
||||
|
#navs {\ |
||||
|
height: 40px;\ |
||||
|
width: 400px;\ |
||||
|
position: relative;\ |
||||
|
}\ |
||||
|
footer {\ |
||||
|
height: 5%;\ |
||||
|
text-align: center;\ |
||||
|
width: 100%;\ |
||||
|
margin-top: 100px;\ |
||||
|
}\ |
||||
|
.clear {\ |
||||
|
clear: left;\ |
||||
|
}\ |
||||
|
#hbs_text {\ |
||||
|
text-align: left;\ |
||||
|
width: 400px;\ |
||||
|
text-indent: 20px;\ |
||||
|
}\ |
||||
|
</style>\ |
||||
|
<meta charset=\"UTF-8\">\
|
||||
|
<meta http-equiv=\"refresh\" content=\"1\">\
|
||||
|
</head>\ |
||||
|
<body>\ |
||||
|
\ |
||||
|
<div id=\"main_block\" align=\"center\">\
|
||||
|
<h2>Лабораторная работа</h2>\ |
||||
|
<h3>Высокочувствительный оптодатчик ADPD2214</h3>\ |
||||
|
<p id=\"hbs_text\">Применяется для измерения пульса, расчета фотоплетизмограммы. Низкое энергопотребление, а также управляемое выключение\
|
||||
|
этого электроприбора позволяет использовать его в портативных устройствах.\ |
||||
|
</p>\ |
||||
|
<p id=\"hbs_text\">Также применяется в химическом анализе. Частота обновления графика - 1 раз в двадцать секунд. Данные с сенсора снимаются\
|
||||
|
с частотой в 20Hz. </p>\ |
||||
|
\ |
||||
|
<canvas id=\"myCanvas\" width=\"400\" height=\"200\" style=\"border:1px solid #3c70ff;\">\
|
||||
|
Браузер устарел!\ |
||||
|
</canvas>\ |
||||
|
\ |
||||
|
"}; |
||||
|
|
||||
|
const char script_begin[] PROGMEM = { |
||||
|
"<script>\
|
||||
|
var c = document.getElementById(\"myCanvas\");\
|
||||
|
var context = c.getContext(\"2d\");\
|
||||
|
var randomNumbers, randNumsLength;\ |
||||
|
context.moveTo(0, 200);"}; |
||||
|
|
||||
|
const char script_end[] PROGMEM = { |
||||
|
"context.stroke();\
|
||||
|
context.font = \"50px Arial\";\
|
||||
|
context.fillText(\"122\",300,170);\
|
||||
|
</script>"}; |
||||
|
|
||||
|
const char html_end[] PROGMEM = { |
||||
|
"<div id=\"navs\">\
|
||||
|
<button onclick=\"window.location.href='/acc.html?f=0'\" class=\"button\">Акселерометр</button>\
|
||||
|
</div>\ |
||||
|
<div class=\"clear\"></div>\
|
||||
|
\ |
||||
|
</div>\ |
||||
|
<footer>\ |
||||
|
Тамбовский Государственный Технический Университет 2017 г.\ |
||||
|
</footer>\ |
||||
|
</body>\ |
||||
|
</html>"}; |
||||
|
|
||||
|
static int getHtml(parts p, char &adr, uint16_t buf_size, uint16_t bias) |
||||
|
{ |
||||
|
char *buffer = &adr; |
||||
|
const char *html_part; |
||||
|
int length = 0; |
||||
|
switch (p) |
||||
|
{ |
||||
|
case HTML_BEGIN: |
||||
|
html_part = html_begin; |
||||
|
break; |
||||
|
case HTML_END: |
||||
|
html_part = html_end; |
||||
|
break; |
||||
|
case STYLE: |
||||
|
html_part = style; |
||||
|
break; |
||||
|
case SCRIPT_BEGIN: |
||||
|
html_part = script_begin; |
||||
|
break; |
||||
|
case SCRIPT_END: |
||||
|
html_part = script_end; |
||||
|
break; |
||||
|
} |
||||
|
length = strlen_P(html_part); |
||||
|
for (int i = 0; i != length; i++) |
||||
|
{ |
||||
|
if (i > buf_size) |
||||
|
return i; |
||||
|
buffer[i + bias] = pgm_read_byte_near(html_part + i); |
||||
|
} |
||||
|
return length; |
||||
|
} |
@ -0,0 +1,120 @@ |
|||||
|
#include <Arduino.h> |
||||
|
#include <ESP8266WiFi.h> |
||||
|
#include <WiFiClient.h> |
||||
|
#include <ESP8266WebServer.h> |
||||
|
#include <ESP8266mDNS.h> |
||||
|
#include <DHT12.h> |
||||
|
#include <html.h> |
||||
|
|
||||
|
const char *ssid = "NodeMCU"; |
||||
|
const char *password = "kvartira138"; |
||||
|
|
||||
|
ESP8266WebServer server(80); |
||||
|
|
||||
|
DHT12 dht12(5, true); |
||||
|
|
||||
|
const int led = 13; |
||||
|
|
||||
|
long int lastUpdate = 0; |
||||
|
int t12 = 0; |
||||
|
int h12 = 0; |
||||
|
int acc = 0; |
||||
|
const int graph_size = 200; |
||||
|
int graph1[graph_size] = { 200 }; |
||||
|
int graph1counter = 0; |
||||
|
|
||||
|
|
||||
|
|
||||
|
void handleRoot() |
||||
|
{ |
||||
|
const int arr_size = 10000; |
||||
|
char *html_code = new char[arr_size]; |
||||
|
memset(html_code, '\0', sizeof(char)*arr_size); |
||||
|
|
||||
|
int16_t bias = 0; |
||||
|
int16_t bias2 = 0; |
||||
|
bias += getHtml(HTML_BEGIN, *html_code, arr_size, 0); |
||||
|
bias += getHtml(STYLE, *html_code, arr_size, bias); |
||||
|
bias += getHtml(SCRIPT_BEGIN, *html_code, arr_size, bias); |
||||
|
for (int i = 0; i != graph_size - 1; i++) { |
||||
|
bias += snprintf((html_code+bias), arr_size - bias, "context.lineTo(%i*2, %i);", i, graph1[i]); |
||||
|
} |
||||
|
bias += getHtml(SCRIPT_END, *html_code, arr_size, bias); |
||||
|
bias += snprintf( |
||||
|
(html_code+bias), arr_size - bias, |
||||
|
"<br> Current temperature: %i \
|
||||
|
<br> Current humudity: %i \ |
||||
|
<br />Current accelerometr: %i", |
||||
|
t12, h12, acc); |
||||
|
|
||||
|
bias += getHtml(HTML_END, *html_code, arr_size, bias); |
||||
|
|
||||
|
server.send(200, "text/html", html_code); |
||||
|
delete[] html_code; |
||||
|
} |
||||
|
|
||||
|
void updateDHT() |
||||
|
{ |
||||
|
if ((millis() - lastUpdate) > 20) |
||||
|
{ |
||||
|
// t12 = (int)dht12.readTemperature();
|
||||
|
// int t12_remapped = map(t12, -20, 100, 200, 0);
|
||||
|
// h12 = (int)dht12.readHumidity();
|
||||
|
acc = map(analogRead(A0), 512, 768, 200, 0); |
||||
|
if (graph1counter < graph_size - 1) { |
||||
|
graph1[graph1counter] = acc; |
||||
|
graph1counter++; |
||||
|
} else { |
||||
|
for(int i = 0; i != graph1counter; i++) { |
||||
|
graph1[i] = graph1[i + 1]; |
||||
|
} |
||||
|
graph1[graph1counter] = acc; |
||||
|
} |
||||
|
lastUpdate = millis(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void handleNotFound() |
||||
|
{ |
||||
|
String message = "File Not Found\n\n"; |
||||
|
message += "URI: "; |
||||
|
message += server.uri(); |
||||
|
message += "\nMethod: "; |
||||
|
message += (server.method() == HTTP_GET) ? "GET" : "POST"; |
||||
|
message += "\nArguments: "; |
||||
|
message += server.args(); |
||||
|
message += "\n"; |
||||
|
for (uint8_t i = 0; i < server.args(); i++) |
||||
|
{ |
||||
|
message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; |
||||
|
} |
||||
|
server.send(404, "text/plain", message); |
||||
|
} |
||||
|
|
||||
|
void setup(void) |
||||
|
{ |
||||
|
pinMode(A0, INPUT); |
||||
|
Serial.begin(115200); |
||||
|
WiFi.softAP(ssid); |
||||
|
|
||||
|
IPAddress myIP = WiFi.softAPIP(); |
||||
|
Serial.print("AP IP address: "); |
||||
|
Serial.println(myIP); |
||||
|
|
||||
|
server.on("/", handleRoot); |
||||
|
|
||||
|
server.on("/inline", []() { |
||||
|
server.send(200, "text/plain", "this works as well"); |
||||
|
}); |
||||
|
|
||||
|
server.onNotFound(handleNotFound); |
||||
|
|
||||
|
server.begin(); |
||||
|
Serial.println("HTTP server started"); |
||||
|
} |
||||
|
|
||||
|
void loop(void) |
||||
|
{ |
||||
|
updateDHT(); |
||||
|
server.handleClient(); |
||||
|
} |
Loading…
Reference in new issue