Library to manage Inovafitness SDS021 particles sensor
Dependents: LoRaWAN-demo-72-bootcamp SDS021Test
Sds021.cpp
- Committer:
- abouillot
- Date:
- 2017-01-28
- Revision:
- 0:0c1a6a29b8c4
- Child:
- 1:fb3d61ffd503
File content as of revision 0:0c1a6a29b8c4:
/*! * Sds021.cpp * * Control the inovafitness particles sensor SDS021 * * Copyright (c) 2017 - Alexandre Bouillot github.com/abouillot * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documnetation 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 * furished 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 OR 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. */ #include "Sds021.h" char* SDS21::prepareMessage(SDS21::action_t action, bool set, int address, int value) { // reset command content memset(outMessage, 0, kOutputLength); // Sets common message values outMessage[0] = head; outMessage[1] = commandCmd; outMessage[2] = action; outMessage[3] = set; outMessage[4] = value; outMessage[15] = address >> 8; outMessage[16] = address & 0xFF; outMessage[kOutputLength - 1] = tail; return outMessage; } char SDS21::calcCheckSum(char* buffer, int start_idx, int stop_idx) { int chk = 0; for (int i = start_idx; i < stop_idx; i++) chk += buffer[i]; chk &= 0xFF; return (char)chk; } bool SDS21::checkSum(char* buffer, int start_idx, int stop_idx) { return calcCheckSum(buffer, start_idx, stop_idx) == buffer[stop_idx]; } void SDS21::writeMessage(char* buffer) { // Calculates and stores checksum in output buffer outMessage[17] = calcCheckSum(outMessage, 2, 17); _sds021.write(outMessage, kOutputLength); // Waits for software serial to finish sending message // delay(20); // (19 bytes * 8 bits * 0.104 ms = 15.808 ms minimum) // delete[] buffer; while (!update()); } bool SDS21::update() { bool updated = false; // Check Serial input buffer for a message while (_sds021.readable()) { int bufPos = 0; // Clear the local buffer memset(inMessage, 0, kInputLength); do { while(!_sds021.readable()) ; inMessage[bufPos] = _sds021.getc(); } while (inMessage[bufPos] != head); while (++bufPos < kInputLength) { while(!_sds021.readable()) ; inMessage[bufPos] = _sds021.getc(); } for (int i=0; i<kInputLength; i++) { printf("%02x_", inMessage[i]); } printf("\n"); // Update local values if message is valid if (checkSum(inMessage)) { char command_id = inMessage[1]; // Parse data frame if (command_id == dataCmd) { _PM2_5 = (float)((inMessage[3] << 8) + inMessage[2]) / 10.0; _PM10 = (float)((inMessage[5] << 8) + inMessage[4]) / 10.0; } // Parse reply frame else if (command_id == replyCmd) { char action = inMessage[2]; if (action == modeAct) _mode = inMessage[4]; else if (action == stateAct) _state = inMessage[4]; else if (action == intervalAct) _interval = inMessage[4]; else if (action == versionAct) { _firmware.year = inMessage[3]; _firmware.month = inMessage[4]; _firmware.day = inMessage[5]; } } // Update device ID _id = (inMessage[6] << 8) + inMessage[7]; updated = true; } else printf("checksum error %02x %02x\n", calcCheckSum(inMessage, 2, 8), inMessage[8]); } return updated; } void SDS21::setId(int new_id) { // Compiles the message prepareMessage(idAct, true, _id); outMessage[13] = new_id >> 8; outMessage[14] = new_id & 0xFF; for (int i=0; i<kOutputLength; i++) printf("%02x.", outMessage[i]); printf("\n"); writeMessage(outMessage); } void SDS21::setPassiveMode(bool passive) { // Compiles the message prepareMessage(modeAct, true, _id, passive); writeMessage(outMessage); } void SDS21::readData() { prepareMessage(queryAct, false, _id); writeMessage(outMessage); } void SDS21::setInterval(uint8_t minutes) { // Clamps minutes between 0-30 if (minutes > 30) minutes = 30; // Compiles the message prepareMessage(intervalAct, true, _id, minutes); writeMessage(outMessage); } void SDS21::setAwake(bool working) { // Compiles the message prepareMessage(stateAct, true, _id, working); writeMessage(outMessage); } SDS21::version_t SDS21::getVersion() { // Compiles the message prepareMessage(versionAct, true, _id); writeMessage(outMessage); return _firmware; }