void onSetAcceleration() { float accel = cmdMessenger.readFloatArg(); leftStepper.setAcceleration(accel); rightStepper.setAcceleration(accel); cmdMessenger.sendCmd(kStatus, "Acceleration set"); }
void onSetSpeed() { float speed = cmdMessenger.readFloatArg(); leftStepper.setSpeed(speed); rightStepper.setSpeed(speed); cmdMessenger.sendCmd(kStatus, "Speed set"); }
void onSetAngleOutputLimits() { Serial.println("Receiving Angle output limits command..."); float lMin, lMax; readLimitsArgs(&lMin, &lMax); anglePID.SetOutputLimits(lMin, lMax); cmdMessenger.sendCmd(kStatus, "Angle output limits set"); }
void onSetAnglePID() { Serial.println("Receiving Angle tuning command..."); float Kp, Ki, Kd; readTuningArgs(&Kp, &Ki, &Kd); anglePID.SetTunings(Kp, Ki, Kd); cmdMessenger.sendCmd(kStatus, "Angle PID tuned"); }
void initCommands() { Serial.println("Init command..."); Serial1.begin(57600); cmdMessenger.printLfCr(); cmdMessenger.attach(onUnknownCommand); cmdMessenger.attach(kSetAnglePID, onSetAnglePID); cmdMessenger.attach(kSetAngleOutputLimits, onSetAngleOutputLimits); cmdMessenger.attach(kSetAcceleration, onSetAcceleration); cmdMessenger.attach(kSetSpeed, onSetSpeed); cmdMessenger.attach(kSetAverage, onSetAverage); cmdMessenger.attach(kRecalibrate, onRecalibrate); Timer3.getAvailable().attachInterrupt(processCommands).setPeriod(100000).start(); cmdMessenger.sendCmd(kStatus, "System ready"); }
void setup() { delay(1000); Serial.begin(38400); sysStatus = sysBootTest(); if (!((sysStatus==SYS_STATUS_NO_CLIMATE) || (sysStatus==SYS_STATUS_NO_SENSORS))) { climateSensor.settings.commInterface = I2C_MODE; climateSensor.settings.I2CAddress = 0x76; climateSensor.settings.runMode = 3; climateSensor.settings.tStandby = 5; climateSensor.settings.filter = 0; climateSensor.settings.tempOverSample = 1; climateSensor.settings.pressOverSample = 1; climateSensor.settings.humidOverSample = 1; climateSensor.begin(); } if (!((sysStatus==SYS_STATUS_NO_ALS) || (sysStatus==SYS_STATUS_NO_SENSORS))) { alsSensor.alsConf(0x4C); alsSensor.psConf(0x0E, 0x08, 0, 0x07); alsSensor.ps(); alsSensor.lux(); } Timer1.initialize(400); Timer1.attachInterrupt(sysTaskTimer); Timer1.pwm(LEDPIN, 0); sysLoadSettings(); if (sensorPsCalibrated) { alsSensor.psSetCanc(psCal); ps=alsSensor.ps(); lux=alsSensor.lux(); } cmdMessenger.printLfCr(); attachCommandCallbacks(); cmdMessenger.sendCmd(kRStatus,sysStatus); }
void onReturnLuxQuery() { lux = alsSensor.lux(); cmdMessenger.sendCmd(kRLux, lux); }
void onReturnPresQuery() { cmdMessenger.sendCmd(kRPres, pressure); }
void onReturnHumiQuery() { cmdMessenger.sendCmd(kRHumi, humidity); }
void onReturnTempQuery() { cmdMessenger.sendCmd(kRTemp, temperature); }
void onDataReturnQueryInt() { cmdMessenger.sendCmd(kRDataQueryInt, sysDataPushInterval); }
//Tasker Functions void sysTaskProcessor(void) { switch (sysTaskFlag) { case SYS_TASK_DEFAULT: { sensorDataReady = false; if (!sensorDataReady) { if (sensorPollALS) { lux = alsSensor.lux(); } if (sensorPollPS) { ps = alsSensor.ps(); } temperature = climateSensor.readTempC(); humidity = climateSensor.readHumidity(); pressure = climateSensor.readPressure(); } sensorDataReady = true; switch (ledControlMode){ case LED_CONTROL_MODE_ALS: if(!sensorPollALS) { sensorPollALS = true; } if (lux <= sensorALSTriggerL) { ledFadeTarget = ledFadeTargetMax; } else if (lux >= sensorALSTriggerH) { ledFadeTarget = ledFadeTargetMin; } break; case LED_CONTROL_MODE_PS: ledPSControl(); break; case LED_CONTROL_MODE_ALS_PS: if (lux <= sensorALSTriggerL) { ledPSControl(); } break; case LED_CONTROL_MODE_OFF: ledFadeTarget = 0; break; default: break; } break; } case SYS_TASK_PUSH_DATA: { if (sensorDataPushed == false) { if (sensorDataReady) { sensorDataPushed = true; cmdMessenger.sendCmd(kRTemp, temperature); cmdMessenger.sendCmd(kRHumi, humidity); cmdMessenger.sendCmd(kRPres, pressure); cmdMessenger.sendCmd(kRLux, lux); if (sensorPsCalibrated) { cmdMessenger.sendCmd(kRPS, ps); } } } sysTaskFlag = SYS_TASK_DEFAULT; break; } case SYS_TASK_NL_CONTROL: { switch (ledControlMode) { case LED_CONTROL_MODE_PS: sensorPollALS = false; ledFadeTarget = ledFadeTargetMax; ledPSTimeoutStart = true; ledPSTimedout = false; break; case LED_CONTROL_MODE_ALS_PS: if (lux <= sensorALSTriggerL) { sensorPollALS = false; ledFadeTarget = ledFadeTargetMax; ledPSTimeoutStart = true; ledPSTimedout = false; } break; default: break; } sysTaskFlag = SYS_TASK_DEFAULT; break; } case SYS_TASK_SAVE_SETTINGS: { sysSaveSettings(); cmdMessenger.sendCmd(kRStatus, SYS_SETTINGS_SAVED); sysTaskFlag = SYS_TASK_DEFAULT; break; } case SYS_TASK_CALIBRATE: { sensorPsCalibrated = false; uint16_t psCalFactor; if(alsSensor.psSetCanc(0)) { delay(500); psCalFactor = alsSensor.psCalibrate(); if (alsSensor.psSetCanc(psCalFactor)) { psCal = psCalFactor; sensorPsCalibrated = true; cmdMessenger.sendCmd(kRCalibratePS, SYS_PS_CALIBRATED); sysTaskFlag = SYS_TASK_SAVE_SETTINGS; } else { cmdMessenger.sendCmd(kRCalibratePS, SYS_PS_CALIBRATE_FAIL); sysTaskFlag = SYS_TASK_DEFAULT; } } else { cmdMessenger.sendCmd(kRCalibratePS, SYS_PS_CALIBRATE_FAIL); sysTaskFlag = SYS_TASK_DEFAULT; } break; } default: { sysTaskFlag = SYS_TASK_DEFAULT; break; } } }
void onSetAverage() { bool _mustUseAverage = cmdMessenger.readBoolArg(); mustUseAverage = _mustUseAverage; cmdMessenger.sendCmd(kStatus, "Use of average toggled"); }
void onUnknownCommand() { Serial.println("Receiving unknown command..."); cmdMessenger.sendCmd(kStatus, "Command without attached callback"); }
void onReturnPSQuery(){ cmdMessenger.sendCmd(kRPS, alsSensor.ps()); }
//Command Functions void onReturnStatus() { cmdMessenger.sendCmd(kRStatus, sysStatus); }
void onLedReturnMode() { cmdMessenger.sendCmd(kRLedMode, ledControlMode); }
void onDataReturnPushMode() { cmdMessenger.sendCmd(kRDataPushMode, sysDataPushMode); }
/** * This method must be called regularily within the loop() function */ void deviceUpdate() { // Blink the LED if (device->ledPin > 0) { if (blinkPattern && millis() > blinkMillis) { digitalWrite(device->ledPin, digitalRead(device->ledPin) == HIGH ? LOW : HIGH); ++blinkIndex; if (blinkPattern[blinkIndex] == 0) { blinkIndex = 0; } blinkMillis = millis() + blinkPattern[blinkIndex]; } } // State machine switch (state) { case STATE_INIT: // -------------------------------------------------------------------------------- // Initial state after powering up DEBUG_PRINTLN_STATE(F("INIT")) #ifdef AUTO_CONFIG if (device->buttonPin > 0) { if (digitalRead(device->buttonPin) == LOW) { activateBlinkPattern(factoryResetBlinkPattern); timeoutMillis = millis() + WAIT_FOR_FACTORYRESET_TIMEOUT; state = STATE_FACTORY_RESET_CONFIRM; break; } } #endif magic = EEPROM.readInt(EEPROM_MAGIC_ADDR); if (magic != MAGIC_NUMBER) { #ifdef AUTO_CONFIG state = STATE_NEW_DEVICE; #else state = STATE_INIT; #endif break; } DEBUG_PRINTLN(F("Valid EEPROM Data")) EEPROM.readBlock(EEPROM_DEVICE_UUID_ADDR, deviceUuid, DEVICE_UUID_LEN); EEPROM.readBlock(EEPROM_DEVICE_NAME_ADDR, deviceName, DEVICE_NAME_MAX_LEN); EEPROM.readBlock(EEPROM_SSID_ADDR, ssid, SSID_MAX_LEN); EEPROM.readBlock(EEPROM_PHRASE_ADDR, phrase, PHRASE_MAX_LEN); DEBUG_DUMP_CONFIG_VALUES() state = STATE_CONNECT_WLAN; break; #ifdef AUTO_CONFIG case STATE_FACTORY_RESET_CONFIRM: // -------------------------------------------------------------------------------- // User must press the button WAIT_FOR_FACTORYRESET_TIMEOUT seconds // before the factory reset is actually executed DEBUG_PRINTLN_STATE(F("FACTORY_RESET_CONFIRM")) if (device->buttonPin > 0) { if (digitalRead(device->buttonPin) == HIGH) { // Factory reset was cancelled delay(10); activateBlinkPattern(NULL); state = STATE_INIT; } else if (millis() > timeoutMillis) { state = STATE_FACTORY_RESET; } } break; #endif #ifdef AUTO_CONFIG case STATE_FACTORY_RESET: // -------------------------------------------------------------------------------- // Perform a factory reset DEBUG_PRINTLN_STATE(F("FACTORY_RESET")) for (int i = 0; i < EEPROM_SIZE; ++i) { EEPROM.writeByte(i, 0xff); } activateBlinkPattern(NULL); state = STATE_INIT; break; #endif #ifdef AUTO_CONFIG case STATE_NEW_DEVICE: // -------------------------------------------------------------------------------- // Entered if this is a new device with no stored valid EEPROM data DEBUG_PRINTLN_STATE(F("NEW_DEVICE")) activateBlinkPattern(newDeviceBlinkPattern); wifly.reset(); wifly.sendCommand("set u b " MAKE_STRING(WIFLY_BAUDRATE) "\r"); wifly.sendCommand("get m\r", "Mac Addr="); wifly.receive((uint8_t *) mac, 17); mac[17] = '\0'; DEBUG_PRINT(F("- MAC: ")) DEBUG_PRINTLN(mac) DEBUG_PRINTLN(F("- Activate AP mode")) wifly.sendCommand("set w j 7\r", "OK"); // Enable AP mode wifly.sendCommand("set w c 6\r", "OK"); sprintf(buf, "set a s Caretaker-%c%c%c%c%c%c%c%c%c%c%c%c\r", mac[0], mac[1], mac[3], mac[4], mac[6], mac[7], mac[9], mac[10], mac[12], mac[13], mac[15], mac[16]); wifly.sendCommand(buf, "OK"); wifly.sendCommand("set a p 0347342d\r", "OK"); wifly.sendCommand("set i d 4\r", "OK"); // Enable DHCP server wifly.sendCommand("set i a 192.168.0.1\r", "OK"); wifly.sendCommand("set i n 255.255.255.0\r", "OK"); wifly.sendCommand("set i g 192.168.0.1\r", "OK"); wifly.save(); wifly.reboot(); state = STATE_WAIT_FOR_DISCOVERY; break; #endif #ifdef AUTO_CONFIG case STATE_WAIT_FOR_DISCOVERY: // -------------------------------------------------------------------------------- // Wait until the configuration app has opened a connection to this device DEBUG_PRINTLN_STATE(F("WAIT_FOR_DISCOVERY")) if (checkWiflyInput("*OPEN*")) { activateBlinkPattern(discoveredBlinkPattern); state = STATE_SEND_INFO; } break; #endif #ifdef AUTO_CONFIG case STATE_SEND_INFO: // -------------------------------------------------------------------------------- // Send information about this device to the configuration app DEBUG_PRINTLN_STATE(F("SEND_INFO")) wifly.println(); // Other side receives "*HELLO*\n" wifly.println(mac); wifly.println(device->type); wifly.println(device->description); state = STATE_WAIT_FOR_SEND_INFO_ACK; break; #endif #ifdef AUTO_CONFIG case STATE_WAIT_FOR_SEND_INFO_ACK: // -------------------------------------------------------------------------------- // Wait for the receiving confirmation DEBUG_PRINTLN_STATE(F("WAIT_FOR_SEND_INFO_ACK")) if (checkWiflyInput("*CLOS*")) { timeoutMillis = millis() + WAIT_FOR_CONFIG_TIMEOUT; state = STATE_WAIT_FOR_CONFIG; } break; #endif #ifdef AUTO_CONFIG case STATE_WAIT_FOR_CONFIG: // -------------------------------------------------------------------------------- // Configuration app has WAIT_FOR_CONFIG_TIMEOUT seconds to send the configuration DEBUG_PRINTLN_STATE(F("WAIT_FOR_CONFIG")) if (checkWiflyInput("*OPEN*")) { state = STATE_CONFIGURE_DEVICE; } else if (millis() > timeoutMillis) { state = STATE_CONFIG_TIMEOUT; } break; #endif #ifdef AUTO_CONFIG case STATE_CONFIG_TIMEOUT: // -------------------------------------------------------------------------------- // No configuration received, restart discovery process DEBUG_PRINTLN_STATE(F("CONFIG_TIMEOUT")) state = STATE_NEW_DEVICE; break; #endif #ifdef AUTO_CONFIG case STATE_CONFIGURE_DEVICE: // -------------------------------------------------------------------------------- // Read and store the confifuration values DEBUG_PRINTLN_STATE(F("CONFIGURE_DEVICE")) wifly.println(); // Other side receives "*HELLO*\n" if (!(wiflyReadline(deviceUuid, DEVICE_UUID_LEN))) { state = STATE_CONFIG_TIMEOUT; break; } if (!(wiflyReadline(deviceName, DEVICE_NAME_MAX_LEN))) { state = STATE_CONFIG_TIMEOUT; break; } if (!(wiflyReadline(ssid, SSID_MAX_LEN))) { state = STATE_CONFIG_TIMEOUT; break; } if (!(wiflyReadline(phrase, PHRASE_MAX_LEN))) { state = STATE_CONFIG_TIMEOUT; break; } while (!checkWiflyInput("*CLOS*")) { } DEBUG_DUMP_CONFIG_VALUES() EEPROM.writeInt(EEPROM_MAGIC_ADDR, MAGIC_NUMBER); EEPROM.writeBlock(EEPROM_DEVICE_UUID_ADDR, deviceUuid, DEVICE_UUID_LEN); EEPROM.writeBlock(EEPROM_DEVICE_NAME_ADDR, deviceName, DEVICE_NAME_MAX_LEN); EEPROM.writeBlock(EEPROM_SSID_ADDR, ssid, SSID_MAX_LEN); EEPROM.writeBlock(EEPROM_PHRASE_ADDR, phrase, PHRASE_MAX_LEN); activateBlinkPattern(NULL); state = STATE_CONNECT_WLAN; break; #endif case STATE_CONNECT_WLAN: // -------------------------------------------------------------------------------- // Connect to the configured WLAN and start sending broadcast messages DEBUG_PRINTLN_STATE(F("CONNECT_WLAN")) wifly.reset(); wifly.sendCommand("set u b " MAKE_STRING(WIFLY_BAUDRATE) "\r"); wifly.sendCommand("set i h 0.0.0.0\r", "OK"); // UDP auto pairing wifly.sendCommand("set i f 0x40\r", "OK"); // UDP auto pairing wifly.sendCommand("set i d 1\r", "OK"); // DHCP client on wifly.sendCommand("set i p 1\r", "OK"); // Use UDP wifly.sendCommand("set b i 7\r", "OK"); // UDP broadcast interval 8 secs #ifdef BROADCAST_PORT wifly.sendCommand("set b p 44444\r", "OK"); // Set broadcast port to 44444 when debugging #endif wifly.sendCommand("set w a 4\r", "OK"); wifly.sendCommand("set w c 0\r", "OK"); wifly.sendCommand("set w j 1\r", "OK"); snprintf(buf, BUF_LEN, "set w s %s\r", ssid); wifly.sendCommand(buf, "OK"); snprintf(buf, BUF_LEN, "set w p %s\r", phrase); wifly.sendCommand(buf, "OK"); snprintf(buf, BUF_LEN, "set o d %s\r", deviceName); wifly.sendCommand(buf, "OK"); wifly.save(); wifly.reboot(); state = STATE_WAIT_FOR_BROADCAST_RESPONSE; break; case STATE_WAIT_FOR_BROADCAST_RESPONSE: // -------------------------------------------------------------------------------- // Wait until the broadcast receiver sends a broadcast response with the actual // with server IP address DEBUG_PRINTLN_STATE(F("WAIT_FOR_BROADCAST_RESPONSE")) if (checkWiflyInput("*SERVER*\n")) { if (wiflyReadline(serverAddress, SERVER_ADDRESS_LEN)) { snprintf(buf, BUF_LEN, "- Broadcast response from server: %s", serverAddress); DEBUG_PRINTLN(buf); // Set the server IP address for UDP transmissions // Disable UDP broadcast snprintf(buf, BUF_LEN, "set i h %s\r", serverAddress); wifly.sendCommand(buf, "OK"); wifly.sendCommand("set b i 0\r", "OK"); wifly.save(); wifly.dataMode(); state = STATE_REGISTER_WITH_SERVER; } } break; case STATE_REGISTER_WITH_SERVER: // -------------------------------------------------------------------------------- // Send a registration request to the server, containing all device information: DEBUG_PRINTLN_STATE(F("REGISTER_WITH_SERVER")) messenger.sendCmdStart(MSG_REGISTER_REQUEST); messenger.sendCmdArg(deviceUuid); messenger.sendCmdArg(device->type); messenger.sendCmdArg(deviceName); messenger.sendCmdArg(device->description); if (device->sendServerRegisterParams) { (*device->sendServerRegisterParams)(); } messenger.sendCmdEnd(); timeoutMillis = millis() + WAIT_FOR_REGISTRATION_TIMEOUT; state = STATE_WAIT_FOR_REGISTER_WITH_SERVER_RESPONSE; break; case STATE_WAIT_FOR_REGISTER_WITH_SERVER_RESPONSE: // -------------------------------------------------------------------------------- // Wait until the server responds to our registration request DEBUG_PRINTLN_STATE(F("WAIT_FOR_REGISTER_WITH_SERVER_RESPONSE")) if (millis() > timeoutMillis) { state = STATE_REGISTER_WITH_SERVER; } else { messenger.feedinSerialData(); } break; case STATE_OPERATIONAL: // -------------------------------------------------------------------------------- // Normal operational mode DEBUG_PRINTLN_STATE(F("OPERATIONAL")) if (millis() > nextPingMillis) { messenger.sendCmd(MSG_PING); nextPingMillis = millis() + PING_INTERVAL; } messenger.feedinSerialData(); break; } }
void onRecalibrate() { angleSetpoint = calibrateSensor(); cmdMessenger.sendCmd(kStatus, "Calibration done"); }