Library to manage Inovafitness SDS021 particles sensor

Dependents:   LoRaWAN-demo-72-bootcamp SDS021Test

Committer:
abouillot
Date:
Mon Jan 30 21:48:36 2017 +0000
Revision:
3:fd34f67797d9
Parent:
2:49822e10d111
Fixed usage bug, where the third parameter in not speed but buffer size

Who changed what in which revision?

UserRevisionLine numberNew contents of line
abouillot 0:0c1a6a29b8c4 1 /*!
abouillot 0:0c1a6a29b8c4 2 * Sds021.cpp
abouillot 0:0c1a6a29b8c4 3 *
abouillot 0:0c1a6a29b8c4 4 * Control the inovafitness particles sensor SDS021
abouillot 0:0c1a6a29b8c4 5 *
abouillot 0:0c1a6a29b8c4 6 * Copyright (c) 2017 - Alexandre Bouillot github.com/abouillot
abouillot 0:0c1a6a29b8c4 7 *
abouillot 0:0c1a6a29b8c4 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
abouillot 0:0c1a6a29b8c4 9 * of this software and associated documnetation files (the "Software"), to deal
abouillot 0:0c1a6a29b8c4 10 * in the Software without restriction, including without limitation the rights
abouillot 0:0c1a6a29b8c4 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
abouillot 0:0c1a6a29b8c4 12 * copies of the Software, and to permit persons to whom the Software is
abouillot 0:0c1a6a29b8c4 13 * furished to do so, subject to the following conditions:
abouillot 0:0c1a6a29b8c4 14 *
abouillot 0:0c1a6a29b8c4 15 * The above copyright notice and this permission notice shall be included in
abouillot 0:0c1a6a29b8c4 16 * all copies or substantial portions of the Software.
abouillot 0:0c1a6a29b8c4 17 *
abouillot 0:0c1a6a29b8c4 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
abouillot 0:0c1a6a29b8c4 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
abouillot 0:0c1a6a29b8c4 20 * FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
abouillot 0:0c1a6a29b8c4 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
abouillot 0:0c1a6a29b8c4 22 * LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
abouillot 0:0c1a6a29b8c4 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
abouillot 0:0c1a6a29b8c4 24 * THE SOFTWARE.
abouillot 0:0c1a6a29b8c4 25 */
abouillot 2:49822e10d111 26
abouillot 2:49822e10d111 27 #include "Sds021.h"
abouillot 0:0c1a6a29b8c4 28
abouillot 1:fb3d61ffd503 29 char* SDS021::prepareMessage(SDS021::action_t action, bool set, int address, int value)
abouillot 0:0c1a6a29b8c4 30 {
abouillot 0:0c1a6a29b8c4 31 // reset command content
abouillot 0:0c1a6a29b8c4 32 memset(outMessage, 0, kOutputLength);
abouillot 0:0c1a6a29b8c4 33
abouillot 0:0c1a6a29b8c4 34 // Sets common message values
abouillot 0:0c1a6a29b8c4 35 outMessage[0] = head;
abouillot 0:0c1a6a29b8c4 36 outMessage[1] = commandCmd;
abouillot 0:0c1a6a29b8c4 37 outMessage[2] = action;
abouillot 0:0c1a6a29b8c4 38 outMessage[3] = set;
abouillot 0:0c1a6a29b8c4 39 outMessage[4] = value;
abouillot 0:0c1a6a29b8c4 40 outMessage[15] = address >> 8;
abouillot 0:0c1a6a29b8c4 41 outMessage[16] = address & 0xFF;
abouillot 0:0c1a6a29b8c4 42 outMessage[kOutputLength - 1] = tail;
abouillot 0:0c1a6a29b8c4 43
abouillot 0:0c1a6a29b8c4 44 return outMessage;
abouillot 0:0c1a6a29b8c4 45 }
abouillot 0:0c1a6a29b8c4 46
abouillot 1:fb3d61ffd503 47 char SDS021::calcCheckSum(char* buffer, int start_idx, int stop_idx)
abouillot 0:0c1a6a29b8c4 48 {
abouillot 0:0c1a6a29b8c4 49 int chk = 0;
abouillot 0:0c1a6a29b8c4 50 for (int i = start_idx; i < stop_idx; i++)
abouillot 0:0c1a6a29b8c4 51 chk += buffer[i];
abouillot 0:0c1a6a29b8c4 52 chk &= 0xFF;
abouillot 0:0c1a6a29b8c4 53 return (char)chk;
abouillot 0:0c1a6a29b8c4 54 }
abouillot 0:0c1a6a29b8c4 55
abouillot 1:fb3d61ffd503 56 bool SDS021::checkSum(char* buffer, int start_idx, int stop_idx)
abouillot 0:0c1a6a29b8c4 57 {
abouillot 0:0c1a6a29b8c4 58 return calcCheckSum(buffer, start_idx, stop_idx) == buffer[stop_idx];
abouillot 0:0c1a6a29b8c4 59 }
abouillot 0:0c1a6a29b8c4 60
abouillot 1:fb3d61ffd503 61 void SDS021::writeMessage(char* buffer)
abouillot 0:0c1a6a29b8c4 62 {
abouillot 0:0c1a6a29b8c4 63 // Calculates and stores checksum in output buffer
abouillot 0:0c1a6a29b8c4 64 outMessage[17] = calcCheckSum(outMessage, 2, 17);
abouillot 0:0c1a6a29b8c4 65 _sds021.write(outMessage, kOutputLength);
abouillot 0:0c1a6a29b8c4 66
abouillot 0:0c1a6a29b8c4 67 // Waits for software serial to finish sending message
abouillot 0:0c1a6a29b8c4 68 // delay(20); // (19 bytes * 8 bits * 0.104 ms = 15.808 ms minimum)
abouillot 0:0c1a6a29b8c4 69 // delete[] buffer;
abouillot 0:0c1a6a29b8c4 70
abouillot 0:0c1a6a29b8c4 71 while (!update());
abouillot 0:0c1a6a29b8c4 72
abouillot 0:0c1a6a29b8c4 73 }
abouillot 0:0c1a6a29b8c4 74
abouillot 1:fb3d61ffd503 75 bool SDS021::update()
abouillot 0:0c1a6a29b8c4 76 {
abouillot 0:0c1a6a29b8c4 77 bool updated = false;
abouillot 0:0c1a6a29b8c4 78
abouillot 0:0c1a6a29b8c4 79 // Check Serial input buffer for a message
abouillot 0:0c1a6a29b8c4 80 while (_sds021.readable()) {
abouillot 0:0c1a6a29b8c4 81 int bufPos = 0;
abouillot 0:0c1a6a29b8c4 82
abouillot 0:0c1a6a29b8c4 83 // Clear the local buffer
abouillot 0:0c1a6a29b8c4 84 memset(inMessage, 0, kInputLength);
abouillot 0:0c1a6a29b8c4 85
abouillot 0:0c1a6a29b8c4 86 do {
abouillot 0:0c1a6a29b8c4 87 while(!_sds021.readable()) ;
abouillot 0:0c1a6a29b8c4 88 inMessage[bufPos] = _sds021.getc();
abouillot 0:0c1a6a29b8c4 89 } while (inMessage[bufPos] != head);
abouillot 0:0c1a6a29b8c4 90
abouillot 0:0c1a6a29b8c4 91
abouillot 0:0c1a6a29b8c4 92 while (++bufPos < kInputLength) {
abouillot 0:0c1a6a29b8c4 93 while(!_sds021.readable()) ;
abouillot 0:0c1a6a29b8c4 94 inMessage[bufPos] = _sds021.getc();
abouillot 0:0c1a6a29b8c4 95 }
abouillot 2:49822e10d111 96 #ifdef TRACE
abouillot 0:0c1a6a29b8c4 97 for (int i=0; i<kInputLength; i++) {
abouillot 0:0c1a6a29b8c4 98 printf("%02x_", inMessage[i]);
abouillot 0:0c1a6a29b8c4 99 }
abouillot 0:0c1a6a29b8c4 100 printf("\n");
abouillot 2:49822e10d111 101 #endif
abouillot 0:0c1a6a29b8c4 102 // Update local values if message is valid
abouillot 0:0c1a6a29b8c4 103 if (checkSum(inMessage)) {
abouillot 0:0c1a6a29b8c4 104 char command_id = inMessage[1];
abouillot 0:0c1a6a29b8c4 105
abouillot 0:0c1a6a29b8c4 106 // Parse data frame
abouillot 0:0c1a6a29b8c4 107 if (command_id == dataCmd) {
abouillot 0:0c1a6a29b8c4 108 _PM2_5 = (float)((inMessage[3] << 8) + inMessage[2]) / 10.0;
abouillot 0:0c1a6a29b8c4 109 _PM10 = (float)((inMessage[5] << 8) + inMessage[4]) / 10.0;
abouillot 0:0c1a6a29b8c4 110 }
abouillot 0:0c1a6a29b8c4 111
abouillot 0:0c1a6a29b8c4 112 // Parse reply frame
abouillot 0:0c1a6a29b8c4 113 else if (command_id == replyCmd) {
abouillot 0:0c1a6a29b8c4 114 char action = inMessage[2];
abouillot 0:0c1a6a29b8c4 115
abouillot 0:0c1a6a29b8c4 116 if (action == modeAct)
abouillot 0:0c1a6a29b8c4 117 _mode = inMessage[4];
abouillot 0:0c1a6a29b8c4 118 else if (action == stateAct)
abouillot 0:0c1a6a29b8c4 119 _state = inMessage[4];
abouillot 0:0c1a6a29b8c4 120 else if (action == intervalAct)
abouillot 0:0c1a6a29b8c4 121 _interval = inMessage[4];
abouillot 0:0c1a6a29b8c4 122 else if (action == versionAct) {
abouillot 0:0c1a6a29b8c4 123 _firmware.year = inMessage[3];
abouillot 0:0c1a6a29b8c4 124 _firmware.month = inMessage[4];
abouillot 0:0c1a6a29b8c4 125 _firmware.day = inMessage[5];
abouillot 0:0c1a6a29b8c4 126 }
abouillot 0:0c1a6a29b8c4 127 }
abouillot 0:0c1a6a29b8c4 128
abouillot 0:0c1a6a29b8c4 129 // Update device ID
abouillot 0:0c1a6a29b8c4 130 _id = (inMessage[6] << 8) + inMessage[7];
abouillot 0:0c1a6a29b8c4 131
abouillot 0:0c1a6a29b8c4 132 updated = true;
abouillot 2:49822e10d111 133 } else {
abouillot 2:49822e10d111 134 #ifdef TRACE
abouillot 0:0c1a6a29b8c4 135 printf("checksum error %02x %02x\n", calcCheckSum(inMessage, 2, 8), inMessage[8]);
abouillot 2:49822e10d111 136 #endif
abouillot 2:49822e10d111 137 }
abouillot 0:0c1a6a29b8c4 138 }
abouillot 0:0c1a6a29b8c4 139
abouillot 0:0c1a6a29b8c4 140 return updated;
abouillot 0:0c1a6a29b8c4 141 }
abouillot 0:0c1a6a29b8c4 142
abouillot 1:fb3d61ffd503 143 void SDS021::setId(int new_id)
abouillot 0:0c1a6a29b8c4 144 {
abouillot 0:0c1a6a29b8c4 145 // Compiles the message
abouillot 0:0c1a6a29b8c4 146 prepareMessage(idAct, true, _id);
abouillot 0:0c1a6a29b8c4 147 outMessage[13] = new_id >> 8;
abouillot 0:0c1a6a29b8c4 148 outMessage[14] = new_id & 0xFF;
abouillot 2:49822e10d111 149 #ifdef TRACE
abouillot 0:0c1a6a29b8c4 150 for (int i=0; i<kOutputLength; i++)
abouillot 0:0c1a6a29b8c4 151 printf("%02x.", outMessage[i]);
abouillot 0:0c1a6a29b8c4 152 printf("\n");
abouillot 2:49822e10d111 153 #endif
abouillot 0:0c1a6a29b8c4 154 writeMessage(outMessage);
abouillot 0:0c1a6a29b8c4 155 }
abouillot 0:0c1a6a29b8c4 156
abouillot 1:fb3d61ffd503 157 void SDS021::setPassiveMode(bool passive)
abouillot 0:0c1a6a29b8c4 158 {
abouillot 0:0c1a6a29b8c4 159 // Compiles the message
abouillot 0:0c1a6a29b8c4 160 prepareMessage(modeAct, true, _id, passive);
abouillot 0:0c1a6a29b8c4 161 writeMessage(outMessage);
abouillot 0:0c1a6a29b8c4 162 }
abouillot 0:0c1a6a29b8c4 163
abouillot 1:fb3d61ffd503 164 void SDS021::readData()
abouillot 0:0c1a6a29b8c4 165 {
abouillot 0:0c1a6a29b8c4 166 prepareMessage(queryAct, false, _id);
abouillot 0:0c1a6a29b8c4 167 writeMessage(outMessage);
abouillot 0:0c1a6a29b8c4 168 }
abouillot 0:0c1a6a29b8c4 169
abouillot 0:0c1a6a29b8c4 170
abouillot 1:fb3d61ffd503 171 void SDS021::setInterval(uint8_t minutes)
abouillot 0:0c1a6a29b8c4 172 {
abouillot 0:0c1a6a29b8c4 173 // Clamps minutes between 0-30
abouillot 0:0c1a6a29b8c4 174 if (minutes > 30)
abouillot 0:0c1a6a29b8c4 175 minutes = 30;
abouillot 0:0c1a6a29b8c4 176
abouillot 0:0c1a6a29b8c4 177 // Compiles the message
abouillot 0:0c1a6a29b8c4 178 prepareMessage(intervalAct, true, _id, minutes);
abouillot 0:0c1a6a29b8c4 179 writeMessage(outMessage);
abouillot 0:0c1a6a29b8c4 180 }
abouillot 0:0c1a6a29b8c4 181
abouillot 1:fb3d61ffd503 182 void SDS021::setAwake(bool working)
abouillot 0:0c1a6a29b8c4 183 {
abouillot 0:0c1a6a29b8c4 184 // Compiles the message
abouillot 0:0c1a6a29b8c4 185 prepareMessage(stateAct, true, _id, working);
abouillot 0:0c1a6a29b8c4 186 writeMessage(outMessage);
abouillot 0:0c1a6a29b8c4 187 }
abouillot 0:0c1a6a29b8c4 188
abouillot 1:fb3d61ffd503 189 SDS021::version_t SDS021::getVersion()
abouillot 0:0c1a6a29b8c4 190 {
abouillot 0:0c1a6a29b8c4 191 // Compiles the message
abouillot 0:0c1a6a29b8c4 192 prepareMessage(versionAct, true, _id);
abouillot 0:0c1a6a29b8c4 193 writeMessage(outMessage);
abouillot 0:0c1a6a29b8c4 194
abouillot 0:0c1a6a29b8c4 195 return _firmware;
abouillot 0:0c1a6a29b8c4 196 }