void MainWnd::OnOptionsFrameskipThrottleOther() { Throttle dlg; int v = dlg.DoModal(); if(v) theApp.throttle = v; }
void MainWnd::OnOptionsFrameskipThrottleOther() { Throttle dlg; unsigned short v = (unsigned short)dlg.DoModal(); if( v ) { theApp.updateThrottle( v ); theApp.autoFrameSkip = false; } }
void MainWnd::OnOptionsFrameskipThrottleOther() { Throttle dlg; int v = (int)dlg.DoModal(); if( v ) { theApp.throttle = v; theApp.autoFrameSkip = false; } }
void MotorController::handleTick() { uint8_t forwardSwitch, reverseSwitch; gearSwitch = GS_FORWARD; Throttle *accelerator = DeviceManager::getInstance()->getAccelerator(); Throttle *brake = DeviceManager::getInstance()->getBrake(); if (accelerator) throttleRequested = accelerator->getLevel(); if (brake && brake->getLevel() < -10 && brake->getLevel() < accelerator->getLevel()) //if the brake has been pressed it overrides the accelerator. throttleRequested = brake->getLevel(); if (prechargeTime == 0) donePrecharge = true; if (!donePrecharge) { if (prechargeSoFar < prechargeTime) { prechargeSoFar += (getTickInterval() / 1000); } else { Logger::info("Done with precharge."); setOutput(mainContactorRelay, true); setOutput(prechargeRelay, false); donePrecharge = true; } } //Logger::debug("Throttle: %d", throttleRequested); }
/* * Get parameters from devices and forward them to ichip. * This is required to initially set-up the */ void ICHIPWIFI::loadParameters() { MotorController *motorController = DeviceManager::getInstance()->getMotorController(); Throttle *accelerator = DeviceManager::getInstance()->getAccelerator(); Throttle *brake = DeviceManager::getInstance()->getBrake(); PotThrottleConfiguration *acceleratorConfig = NULL; PotThrottleConfiguration *brakeConfig = NULL; MotorControllerConfiguration *motorConfig = NULL; Logger::info("loading config params to ichip/wifi"); if (accelerator) acceleratorConfig = (PotThrottleConfiguration *)accelerator->getConfiguration(); if (brake) brakeConfig = (PotThrottleConfiguration *)brake->getConfiguration(); if (motorController) motorConfig = (MotorControllerConfiguration *)motorController->getConfiguration(); if (acceleratorConfig) { setParam("numThrottlePots", acceleratorConfig->numberPotMeters); setParam("throttleSubType", acceleratorConfig->throttleSubType); setParam("throttleMin1", acceleratorConfig->minimumLevel1); setParam("throttleMin2", acceleratorConfig->minimumLevel2); setParam("throttleMax1", acceleratorConfig->maximumLevel1); setParam("throttleMax2", acceleratorConfig->maximumLevel2); setParam("throttleRegenMax", (uint16_t)(acceleratorConfig->positionRegenMaximum / 10)); setParam("throttleRegenMin", (uint16_t)(acceleratorConfig->positionRegenMinimum / 10)); setParam("throttleFwd", (uint16_t)(acceleratorConfig->positionForwardMotionStart / 10)); setParam("throttleMap", (uint16_t)(acceleratorConfig->positionHalfPower / 10)); setParam("throttleMinRegen", acceleratorConfig->minimumRegen); setParam("throttleMaxRegen", acceleratorConfig->maximumRegen); setParam("throttleCreep", acceleratorConfig->creep); } if (brakeConfig) { setParam("brakeMin", brakeConfig->minimumLevel1); setParam("brakeMax", brakeConfig->maximumLevel1); setParam("brakeMinRegen", brakeConfig->minimumRegen); setParam("brakeMaxRegen", brakeConfig->maximumRegen); } if (motorConfig) { setParam("speedMax", motorConfig->speedMax); setParam("torqueMax", (uint16_t)(motorConfig->torqueMax / 10)); // skip the tenth's } }
void Heartbeat::handleTick() { // Print a dot if no other output has been made since the last tick if (Logger::getLastLogTime() < lastTickTime) { SerialUSB.print('.'); if ((++dotCount % 80) == 0) { SerialUSB.println(); } } lastTickTime = millis(); if (led) { digitalWrite(BLINK_LED, HIGH); } else { digitalWrite(BLINK_LED, LOW); } led = !led; if (throttleDebug) { MotorController *motorController = DeviceManager::getInstance()->getMotorController(); Throttle *accelerator = DeviceManager::getInstance()->getAccelerator(); Throttle *brake = DeviceManager::getInstance()->getBrake(); Logger::console(""); if (motorController) { Logger::console("Motor Controller Status: isRunning: %T isFaulted: %T", motorController->isRunning(), motorController->isFaulted()); } Logger::console("AIN0: %d, AIN1: %d, AIN2: %d, AIN3: %d", getAnalog(0), getAnalog(1), getAnalog(2), getAnalog(3)); Logger::console("DIN0: %d, DIN1: %d, DIN2: %d, DIN3: %d", getDigital(0), getDigital(1), getDigital(2), getDigital(3)); Logger::console("DOUT0: %d, DOUT1: %d, DOUT2: %d, DOUT3: %d,DOUT4: %d, DOUT5: %d, DOUT6: %d, DOUT7: %d", getOutput(0), getOutput(1), getOutput(2), getOutput(3),getOutput(4), getOutput(5), getOutput(6), getOutput(7)); if (accelerator) { Logger::console("Throttle Status: isFaulted: %T level: %i", accelerator->isFaulted(), accelerator->getLevel()); RawSignalData *rawSignal = accelerator->acquireRawSignal(); Logger::console("Throttle rawSignal1: %d, rawSignal2: %d", rawSignal->input1, rawSignal->input2); } if (brake) { Logger::console("Brake Output: %i", brake->getLevel()); RawSignalData *rawSignal = brake->acquireRawSignal(); Logger::console("Brake rawSignal1: %d", rawSignal->input1); } } }
/* * Periodic updates of parameters to ichip RAM. * Also query for changed parameters of the config page. */ void ICHIPWIFI::handleTick() { MotorController* motorController = DeviceManager::getInstance()->getMotorController(); Throttle *accelerator = DeviceManager::getInstance()->getAccelerator(); Throttle *brake = DeviceManager::getInstance()->getBrake(); tickCounter++; // make small slices so the main loop is not blocked for too long if (tickCounter == 1) { if (motorController) { setParam("timeRunning", getTimeRunning()); setParam("torqueRequested", motorController->getTorqueRequested() / 10.0f, 1); setParam("torqueActual", motorController->getTorqueActual() / 10.0f, 1); } if (accelerator) setParam("throttle", accelerator->getLevel() / 10.0f, 1); if (brake) setParam("brake", brake->getLevel() / 10.0f, 1); else setParam("brake", "n/a"); } else if (tickCounter == 2) { if (motorController) { setParam("speedRequested", motorController->getSpeedRequested()); setParam("speedActual", motorController->getSpeedActual()); setParam("dcVoltage", motorController->getDcVoltage() / 10.0f, 1); setParam("dcCurrent", motorController->getDcCurrent() / 10.0f, 1); } } else if (tickCounter == 3) { if (motorController) { setParam("acCurrent", motorController->getAcCurrent() / 10.0f, 1); setParam("bitfield1", motorController->getStatusBitfield1()); setParam("bitfield2", motorController->getStatusBitfield2()); setParam("bitfield3", motorController->getStatusBitfield3()); setParam("bitfield4", motorController->getStatusBitfield4()); } } else if (tickCounter == 4) { if (motorController) { setParam("running", (motorController->isRunning() ? "true" : "false")); setParam("faulted", (motorController->isFaulted() ? "true" : "false")); setParam("warning", (motorController->isWarning() ? "true" : "false")); setParam("gear", (uint16_t) motorController->getGearSwitch()); } } else if (tickCounter > 4) { if (motorController) { setParam("tempMotor", motorController->getTemperatureMotor() / 10.0f, 1); setParam("tempInverter", motorController->getTemperatureInverter() / 10.0f, 1); setParam("tempSystem", motorController->getTemperatureSystem() / 10.0f, 1); setParam("mechPower", motorController->getMechanicalPower() / 10.0f, 1); tickCounter = 0; } getNextParam(); // wait "loadParams" cycles of tickCounter > 4 before sending config parameters // sending them too early after a soft-reset of ichip results in lost data. if (loadParams > 0) { if (loadParams == 1) loadParameters(); loadParams--; } } }
/* * Process the parameter update from ichip we received as a response to AT+iWNXT. * The response usually looks like this : key="value", so the key can be isolated * by looking for the '=' sign and the leading/trailing '"' have to be ignored. */ void ICHIPWIFI::processParameterChange(char *key) { PotThrottleConfiguration *acceleratorConfig = NULL; PotThrottleConfiguration *brakeConfig = NULL; MotorControllerConfiguration *motorConfig = NULL; Throttle *accelerator = DeviceManager::getInstance()->getAccelerator(); Throttle *brake = DeviceManager::getInstance()->getBrake(); MotorController *motorController = DeviceManager::getInstance()->getMotorController(); if (accelerator) acceleratorConfig = (PotThrottleConfiguration *)accelerator->getConfiguration(); if (brake) brakeConfig = (PotThrottleConfiguration *)brake->getConfiguration(); if(motorController) motorConfig = (MotorControllerConfiguration *)motorController->getConfiguration(); char *value = strchr(key, '='); if (value) { value[0] = 0; // replace the '=' sign with a 0 value++; if (value[0] == '"') value++; // if the value starts with a '"', advance one character if (value[strlen(value) - 1] == '"') value[strlen(value) - 1] = 0; // if the value ends with a '"' character, replace it with 0 if (!strcmp(key, "numThrottlePots") && acceleratorConfig) { acceleratorConfig->numberPotMeters = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, "throttleSubType") && acceleratorConfig) { acceleratorConfig->throttleSubType = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, "throttleMin1") && acceleratorConfig) { acceleratorConfig->minimumLevel1 = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, "throttleMin2") && acceleratorConfig) { acceleratorConfig->minimumLevel2 = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, "throttleMax1") && acceleratorConfig) { acceleratorConfig->maximumLevel1 = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, "throttleMax2") && acceleratorConfig) { acceleratorConfig->maximumLevel2 = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, "throttleRegenMax") && acceleratorConfig) { acceleratorConfig->positionRegenMaximum = atol(value) * 10; } else if (!strcmp(key, "throttleRegenMin") && acceleratorConfig) { acceleratorConfig->positionRegenMinimum = atol(value) * 10; accelerator->saveConfiguration(); } else if (!strcmp(key, "throttleFwd") && acceleratorConfig) { acceleratorConfig->positionForwardMotionStart = atol(value) * 10; accelerator->saveConfiguration(); } else if (!strcmp(key, "throttleMap") && acceleratorConfig) { acceleratorConfig->positionHalfPower = atol(value) * 10; accelerator->saveConfiguration(); } else if (!strcmp(key, "throttleMinRegen") && acceleratorConfig) { acceleratorConfig->minimumRegen = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, "throttleMaxRegen") && acceleratorConfig) { acceleratorConfig->maximumRegen = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, "throttleCreep") && acceleratorConfig) { acceleratorConfig->creep = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, "brakeMin") && brakeConfig) { brakeConfig->minimumLevel1 = atol(value); brake->saveConfiguration(); } else if (!strcmp(key, "brakeMax") && brakeConfig) { brakeConfig->maximumLevel1 = atol(value); brake->saveConfiguration(); } else if (!strcmp(key, "brakeMinRegen") && brakeConfig) { brakeConfig->minimumRegen = atol(value); brake->saveConfiguration(); } else if (!strcmp(key, "brakeMaxRegen") && brakeConfig) { brakeConfig->maximumRegen = atol(value); brake->saveConfiguration(); } else if (!strcmp(key, "speedMax") && motorConfig) { motorConfig->speedMax = atol(value); motorController->saveConfiguration(); } else if (!strcmp(key, "torqueMax") && motorConfig) { motorConfig->torqueMax = atol(value) * 10; motorController->saveConfiguration(); } } getNextParam(); // try to get another one immediately }
void SerialConsole::printMenu() { MotorController* motorController = (MotorController*) DeviceManager::getInstance()->getMotorController(); Throttle *accelerator = DeviceManager::getInstance()->getAccelerator(); Throttle *brake = DeviceManager::getInstance()->getBrake(); ICHIPWIFI *wifi = (ICHIPWIFI*) DeviceManager::getInstance()->getDeviceByType(DEVICE_WIFI); //Show build # here as well in case people are using the native port and don't get to see the start up messages SerialUSB.print("Build number: "); SerialUSB.println(CFG_BUILD_NUM); if (motorController) { SerialUSB.println( "Motor Controller Status: isRunning: " + String(motorController->isRunning()) + " isFaulted: " + String(motorController->isFaulted())); } SerialUSB.println("System Menu:"); SerialUSB.println(); SerialUSB.println("Enable line endings of some sort (LF, CR, CRLF)"); SerialUSB.println(); SerialUSB.println("Short Commands:"); SerialUSB.println("h = help (displays this message)"); if (heartbeat != NULL) { SerialUSB.println("L = show raw analog/digital input/output values (toggle)"); } SerialUSB.println("K = set all outputs high"); SerialUSB.println("J = set all outputs low"); //SerialUSB.println("U,I = test EEPROM routines"); SerialUSB.println("E = dump system eeprom values"); SerialUSB.println("z = detect throttle min/max, num throttles and subtype"); SerialUSB.println("Z = save throttle values"); SerialUSB.println("b = detect brake min/max"); SerialUSB.println("B = save brake values"); SerialUSB.println("p = enable wifi passthrough (reboot required to resume normal operation)"); SerialUSB.println("S = show possible device IDs"); SerialUSB.println("w = GEVCU 4.2 reset wifi to factory defaults, setup GEVCU ad-hoc network"); SerialUSB.println("W = GEVCU 5.2 reset wifi to factory defaults, setup GEVCU as 10.0.0.1 Access Point"); SerialUSB.println("s = Scan WiFi for nearby access points"); SerialUSB.println(); SerialUSB.println("Config Commands (enter command=newvalue). Current values shown in parenthesis:"); SerialUSB.println(); Logger::console("LOGLEVEL=%i - set log level (0=debug, 1=info, 2=warn, 3=error, 4=off)", Logger::getLogLevel()); uint8_t systype; sysPrefs->read(EESYS_SYSTEM_TYPE, &systype); Logger::console("SYSTYPE=%i - Set board revision (Dued=2, GEVCU3=3, GEVCU4=4)", systype); DeviceManager::getInstance()->printDeviceList(); if (motorController && motorController->getConfiguration()) { MotorControllerConfiguration *config = (MotorControllerConfiguration *) motorController->getConfiguration(); SerialUSB.println(); SerialUSB.println("MOTOR CONTROLS"); SerialUSB.println(); Logger::console("TORQ=%i - Set torque upper limit (tenths of a Nm)", config->torqueMax); Logger::console("RPM=%i - Set maximum RPM", config->speedMax); Logger::console("REVLIM=%i - How much torque to allow in reverse (Tenths of a percent)", config->reversePercent); Logger::console("COOLFAN=%i - Digital output to turn on cooling fan(0-7, 255 for none)", config->coolFan); Logger::console("COOLON=%i - Inverter temperature C to turn cooling on", config->coolOn); Logger::console("COOLOFF=%i - Inverter temperature C to turn cooling off", config->coolOff); Logger::console("BRAKELT = %i - Digital output to turn on brakelight (0-7, 255 for none)", config->brakeLight); Logger::console("REVLT=%i - Digital output to turn on reverse light (0-7, 255 for none)", config->revLight); Logger::console("ENABLEIN=%i - Digital input to enable motor controller (0-3, 255 for none)", config->enableIn); Logger::console("REVIN=%i - Digital input to reverse motor rotation (0-3, 255 for none)", config->reverseIn); } if (accelerator && accelerator->getConfiguration()) { PotThrottleConfiguration *config = (PotThrottleConfiguration *) accelerator->getConfiguration(); SerialUSB.println(); SerialUSB.println("THROTTLE CONTROLS"); SerialUSB.println(); Logger::console("TPOT=%i - Number of pots to use (1 or 2)", config->numberPotMeters); Logger::console("TTYPE=%i - Set throttle subtype (1=std linear, 2=inverse)", config->throttleSubType); Logger::console("T1ADC=%i - Set throttle 1 ADC pin", config->AdcPin1); Logger::console("T1MN=%i - Set throttle 1 min value", config->minimumLevel1); Logger::console("T1MX=%i - Set throttle 1 max value", config->maximumLevel1); Logger::console("T2ADC=%i - Set throttle 2 ADC pin", config->AdcPin2); Logger::console("T2MN=%i - Set throttle 2 min value", config->minimumLevel2); Logger::console("T2MX=%i - Set throttle 2 max value", config->maximumLevel2); Logger::console("TRGNMAX=%i - Tenths of a percent of pedal where regen is at max", config->positionRegenMaximum); Logger::console("TRGNMIN=%i - Tenths of a percent of pedal where regen is at min", config->positionRegenMinimum); Logger::console("TFWD=%i - Tenths of a percent of pedal where forward motion starts", config->positionForwardMotionStart); Logger::console("TMAP=%i - Tenths of a percent of pedal where 50% throttle will be", config->positionHalfPower); Logger::console("TMINRN=%i - Percent of full torque to use for min throttle regen", config->minimumRegen); Logger::console("TMAXRN=%i - Percent of full torque to use for max throttle regen", config->maximumRegen); Logger::console("TCREEP=%i - Percent of full torque to use for creep (0=disable)", config->creep); } if (brake && brake->getConfiguration()) { PotThrottleConfiguration *config = (PotThrottleConfiguration *) brake->getConfiguration(); SerialUSB.println(); SerialUSB.println("BRAKE CONTROLS"); SerialUSB.println(); Logger::console("B1ADC=%i - Set brake ADC pin", config->AdcPin1); Logger::console("B1MN=%i - Set brake min value", config->minimumLevel1); Logger::console("B1MX=%i - Set brake max value", config->maximumLevel1); Logger::console("BMINR=%i - Percent of full torque for start of brake regen", config->minimumRegen); Logger::console("BMAXR=%i - Percent of full torque for maximum brake regen", config->maximumRegen); } if (motorController && motorController->getConfiguration()) { MotorControllerConfiguration *config = (MotorControllerConfiguration *) motorController->getConfiguration(); SerialUSB.println(); SerialUSB.println("PRECHARGE CONTROLS"); SerialUSB.println(); Logger::console("PREDELAY=%i - Precharge delay time in milliseconds ", config->prechargeR); Logger::console("PRELAY=%i - Which output to use for precharge contactor (255 to disable)", config->prechargeRelay); Logger::console("MRELAY=%i - Which output to use for main contactor (255 to disable)", config->mainContactorRelay); SerialUSB.println(); SerialUSB.println("WIRELESS LAN COMMANDS"); SerialUSB.println(); Logger::console("WIREACH=anycommand - sends ATi+anycommand to WiReach Module"); Logger::console("SSID=anyname - sets broadcast ID to anyname"); Logger::console("IP=192.168.3.10 - sets IP of website to whatever IP is entered"); Logger::console("PWD=secret - sets website configuration password to entered string"); Logger::console("CHANNEL=4 - sets website wireless channel - 1 to 11"); Logger::console("SECURITY=password - sets website wireless connection security for WPA2-AES and password"); SerialUSB.println(); SerialUSB.println("OTHER"); SerialUSB.println(); Logger::console("NOMV=%i - Fully charged pack voltage that automatically resets kWh counter", config->nominalVolt/10); Logger::console("kWh=%d - kiloWatt Hours of energy used", config->kilowattHrs/3600000); Logger::console("OUTPUT=<0-7> - toggles state of specified digital output"); Logger::console("NUKE=1 - Resets all device settings in EEPROM. You have been warned."); } }
void SerialConsole::handleShortCmd() { uint8_t val; MotorController* motorController = (MotorController*) DeviceManager::getInstance()->getMotorController(); Throttle *accelerator = DeviceManager::getInstance()->getAccelerator(); Throttle *brake = DeviceManager::getInstance()->getBrake(); DeviceManager *deviceManager = DeviceManager::getInstance(); switch (cmdBuffer[0]) { case 'h': case '?': case 'H': printMenu(); break; case 'L': if (heartbeat != NULL) { heartbeat->setThrottleDebug(!heartbeat->getThrottleDebug()); if (heartbeat->getThrottleDebug()) { Logger::console("Output raw throttle"); } else { Logger::console("Cease raw throttle output"); } } break; case 'U': Logger::console("Adding a sequence of values from 0 to 255 into eeprom"); for (int i = 0; i < 256; i++) { memCache->Write(1000 + i, (uint8_t) i); } Logger::info("Flushing cache"); memCache->FlushAllPages(); //write everything to eeprom memCache->InvalidateAll(); //remove all data from cache Logger::console("Operation complete."); break; case 'I': Logger::console("Retrieving data previously saved"); for (int i = 0; i < 256; i++) { memCache->Read(1000 + i, &val); Logger::console("%d: %d", i, val); } break; case 'E': Logger::console("Reading System EEPROM values"); for (int i = 0; i < 256; i++) { memCache->Read(EE_SYSTEM_START + i, &val); Logger::console("%d: %d", i, val); } break; case 'K': //set all outputs high for (int tout = 0; tout < NUM_OUTPUT; tout++) setOutput(tout, true); Logger::console("all outputs: ON"); break; case 'J': //set the four outputs low for (int tout = 0; tout < NUM_OUTPUT; tout++) setOutput(tout, false); Logger::console("all outputs: OFF"); break; case 'z': // detect throttle min/max & other details if (accelerator) { ThrottleDetector *detector = new ThrottleDetector(accelerator); detector->detect(); } break; case 'Z': // save throttle settings if (accelerator) { accelerator->saveConfiguration(); } break; case 'b': if (brake) { ThrottleDetector *detector = new ThrottleDetector(brake); detector->detect(); } break; case 'B': if (brake != NULL) { brake->saveConfiguration(); } break; case 'p': Logger::console("PASSTHROUGH MODE - All traffic Serial3 <-> SerialUSB"); //this never stops so basically everything dies. you will have to reboot. int inSerialUSB, inSerial3; while (1 == 1) { inSerialUSB = SerialUSB.read(); inSerial3 = Serial3.read(); if (inSerialUSB > -1) { Serial3.write((char) inSerialUSB); } if (inSerial3 > -1) { SerialUSB.write((char) inSerial3); } } break; case 'S': //there is not really any good way (currently) to auto generate this list //the information just isn't stored anywhere in code. Perhaps we might //think to change that. Otherwise you must remember to update here or //nobody will know your device exists. Additionally, these values are //decoded into decimal from their hex specification in DeviceTypes.h Logger::console("DMOC645 = %X", DMOC645); Logger::console("Brusa DMC5 = %X", BRUSA_DMC5); Logger::console("Brusa Charger = %X", BRUSACHARGE); Logger::console("TCCH Charger = %X", TCCHCHARGE); Logger::console("Pot based accelerator = %X", POTACCELPEDAL); Logger::console("Pot based brake = %X", POTBRAKEPEDAL); Logger::console("CANBus accelerator = %X", CANACCELPEDAL); Logger::console("CANBus brake = %X", CANBRAKEPEDAL); Logger::console("WIFI (iChip2128) = %X", ICHIP2128); Logger::console("Th!nk City BMS = %X", THINKBMS); break; case 's': Logger::console("Finding and listing all nearby WiFi access points"); deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"RP20"); break; case 'W': Logger::console("Setting Wifi Adapter to WPS mode (make sure you press the WPS button on your router)"); // restore factory defaults and give it some time deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"AWPS"); break; case 'w': Logger::console("Resetting wifi to factory defaults and setting up GEVCU4.2 Ad Hoc network"); // restore factory defaults and give it some time // pinMode(43,OUTPUT); // digitalWrite(43, LOW); //Pin 43 held low for 5 seconds puts Version 4.2 in Recovery mode // delay(6000); // digitalWrite(43, HIGH); // delay(3000); deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"FD");//Reset delay(2000); deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"HIF=1"); //Set for RS-232 serial. delay(1000); deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"BDRA");//Auto baud rate selection delay(1000); deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"WLCH=9"); //use whichever channel an AP wants to use delay(1000); deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"WLSI=!GEVCU"); //set for GEVCU aS AP. delay(1000); deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DIP=192.168.3.10"); //enable IP delay(1000); deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DPSZ=8"); //set DHCP server for 8 delay(1000); deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"RPG=secret"); // set the configuration password for /ichip delay(1000); deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"WPWD=secret"); // set the password to update config params delay(1000); deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"AWS=1"); //turn on web server delay(1000); deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DOWN"); //cause a reset to allow it to come up with the settings delay(5000); // a 5 second delay is required for the chip to come back up ! Otherwise commands will be lost deviceManager->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_CONFIG_CHANGE, NULL); // reload configuration params as they were lost Logger::console("Wifi 4.2 initialized"); break; case 'X': setup(); //this is probably a bad idea. Do not do this while connected to anything you care about - only for debugging in safety! break; } }
//TODO: See the processing function below for a more detailed explanation - can't send so many setParam commands in a row void ADAFRUITBLE::handleTick() { MotorController* motorController = DeviceManager::getInstance()->getMotorController(); Throttle *accelerator = DeviceManager::getInstance()->getAccelerator(); Throttle *brake = DeviceManager::getInstance()->getBrake(); BatteryManager *bms = reinterpret_cast<BatteryManager *>(DeviceManager::getInstance()->getDeviceByType(DEVICE_BMS)); uint32_t ms = millis(); uint32_t IOTemp = 0; uint8_t brklt; tickCounter++; if (ms < 1000) return; //wait 1 seconds for things to settle before doing a thing // Do a delayed parameter load once about a second after startup if (!didParamLoad && ms > 5000) { loadParameters(); Logger::console("BLE characteristics loaded..."); bleBitFields.bitfield1 = motorController->getStatusBitfield1(); bleBitFields.bitfield2 = motorController->getStatusBitfield2(); bleBitFields.doUpdate = 1; // DeviceManager::getInstance()->updateWifiByID(BRUSA_DMC5); didParamLoad = true; } if (paramCache.timeRunning != (ms / 1000)) { paramCache.timeRunning = ms / 1000; if (!gatt.setChar(MeasureCharId[0], (uint8_t*)¶mCache.timeRunning, 4)) { Logger::error("Could not update timeRunning"); } else Logger::debug(ADABLUE, "Updated timeRunning"); dumpRawData((uint8_t *)¶mCache.timeRunning, 4); } //every other time - 80ms by default if (tickCounter & 1) { if (motorController) { if ( bleTrqReqAct.torqueRequested != motorController->getTorqueRequested() ) { bleTrqReqAct.torqueRequested = motorController->getTorqueRequested(); bleTrqReqAct.doUpdate = 1; } if ( bleTrqReqAct.torqueActual != motorController->getTorqueActual() ) { bleTrqReqAct.torqueActual = motorController->getTorqueActual(); bleTrqReqAct.doUpdate = 1; } if ( bleSpeeds.speedRequested != motorController->getSpeedRequested() ) { bleSpeeds.speedRequested = motorController->getSpeedRequested(); bleSpeeds.doUpdate = 1; } if ( bleSpeeds.speedActual != motorController->getSpeedActual() ) { bleSpeeds.speedActual = motorController->getSpeedActual(); bleSpeeds.doUpdate = 1; } } if (accelerator) { RawSignalData *rawSignal = accelerator->acquireRawSignal(); if ( bleThrBrkLevels.throttleRawLevel1 != rawSignal->input1) { bleThrBrkLevels.throttleRawLevel1 = rawSignal->input1; bleThrBrkLevels.doUpdate = 1; } if ( bleThrBrkLevels.throttleRawLevel2 != rawSignal->input2) { bleThrBrkLevels.throttleRawLevel2 = rawSignal->input2; bleThrBrkLevels.doUpdate = 1; } if (bleThrBrkLevels.throttlePercentage != accelerator->getLevel() / 10) { bleThrBrkLevels.throttlePercentage = accelerator->getLevel() / 10; bleThrBrkLevels.doUpdate = 1; } } if (brake) { RawSignalData *rawSignal = brake->acquireRawSignal(); if (bleThrBrkLevels.brakeRawLevel != rawSignal->input1) { bleThrBrkLevels.brakeRawLevel = rawSignal->input1; paramCache.brakeNotAvailable = false; bleThrBrkLevels.doUpdate = 1; } if (bleThrBrkLevels.brakePercentage != brake->getLevel() / 10) { bleThrBrkLevels.brakePercentage = brake->getLevel() / 10; bleThrBrkLevels.doUpdate = 1; } } else { if ( paramCache.brakeNotAvailable == true ) { paramCache.brakeNotAvailable = false; // no need to keep sending this bleThrBrkLevels.brakeRawLevel = 0; bleThrBrkLevels.doUpdate = 1; } } } if (tickCounter == 2) { if (bms) { if (blePowerStatus.SOC != bms->getSOC()) { blePowerStatus.SOC = bms->getSOC(); blePowerStatus.doUpdate = 1; } } if (motorController) { //Logger::console("Wifi tick counter 2..."); if ( blePowerStatus.busVoltage != motorController->getDcVoltage() ) { blePowerStatus.busVoltage = motorController->getDcVoltage(); if(blePowerStatus.busVoltage<0) blePowerStatus.busVoltage=0; //if(blePowerStatus.busVoltage>4500) blePowerStatus.busVoltage=4500; blePowerStatus.doUpdate = 1; } if ( blePowerStatus.busCurrent != motorController->getDcCurrent() ) { blePowerStatus.busCurrent = motorController->getDcCurrent(); blePowerStatus.doUpdate = 1; } if ( blePowerStatus.motorCurrent != motorController->getAcCurrent() ) { blePowerStatus.motorCurrent = motorController->getAcCurrent(); blePowerStatus.doUpdate = 1; } if ( blePowerStatus.kwHours != motorController->getKiloWattHours()/3600000 ) { blePowerStatus.kwHours = motorController->getKiloWattHours()/3600000; if(blePowerStatus.kwHours<0)blePowerStatus.kwHours = 0; if(blePowerStatus.kwHours>300)blePowerStatus.kwHours = 300; blePowerStatus.doUpdate = 1; } if ( blePowerStatus.mechPower != motorController->getMechanicalPower() ) { blePowerStatus.mechPower = motorController->getMechanicalPower(); if (blePowerStatus.mechPower<-250)blePowerStatus.mechPower=-250; if (blePowerStatus.mechPower>1500)blePowerStatus.mechPower=1500; blePowerStatus.doUpdate = 1; } //DeviceManager::getInstance()->updateWifi(); } } else if (tickCounter == 3) { if (motorController) { //Logger::console("Wifi tick counter 3..."); if ( bleMaxParams.nomVoltage != motorController->getnominalVolt() ) { bleMaxParams.nomVoltage = motorController->getnominalVolt(); bleMaxParams.doUpdate = 1; } if ( bleBitFields.bitfield1 != motorController->getStatusBitfield1() ) { bleBitFields.bitfield1 = motorController->getStatusBitfield1(); bleBitFields.doUpdate = 1; } if ( bleBitFields.bitfield2 != motorController->getStatusBitfield2() ) { bleBitFields.bitfield2 = motorController->getStatusBitfield2(); bleBitFields.doUpdate = 1; } IOTemp = 0; for (int i = 0; i < 4; i++) { if (getDigital(i)) bleBitFields.digitalInputs |= 1 << i; } if ( bleBitFields.digitalInputs != IOTemp ) { bleBitFields.digitalInputs = IOTemp; bleBitFields.doUpdate = 1; } IOTemp = 0; for (int i = 0; i < 8; i++) { if (getOutput(i)) bleBitFields.digitalOutputs |= 1 << i; } if ( bleBitFields.digitalOutputs != IOTemp ) { bleBitFields.digitalOutputs = IOTemp; bleBitFields.doUpdate = 1; } if ( bleModes.isRunning != motorController->isRunning() ) { bleModes.isRunning = motorController->isRunning(); bleModes.doUpdate = 1; } if ( bleModes.isFaulted != motorController->isFaulted() ) { bleModes.isFaulted = motorController->isFaulted(); bleModes.doUpdate = 1; } if ( bleModes.isWarning != motorController->isWarning() ) { bleModes.isWarning = motorController->isWarning(); bleModes.doUpdate = 1; } if ( bleModes.gear != motorController->getSelectedGear() ) { bleModes.gear = motorController->getSelectedGear(); bleModes.doUpdate = 1; } if ( bleModes.powerMode != motorController->getPowerMode() ) { bleModes.powerMode = motorController->getPowerMode(); bleModes.doUpdate = 1; } } } else if (tickCounter == 4) { if (motorController) { //Logger::console("Wifi tick counter 4..."); if ( bleDigIO.prechargeDuration != motorController->getprechargeR() ) { bleDigIO.prechargeDuration = motorController->getprechargeR(); bleDigIO.doUpdate = 1; } if ( bleDigIO.prechargeRelay != motorController->getprechargeRelay() ) { bleDigIO.prechargeRelay = motorController->getprechargeRelay(); bleDigIO.doUpdate = 1; //Logger::console("Precharge Relay %i", paramCache.prechargeRelay); //Logger::console("motorController:prechargeRelay:%d, paramCache.prechargeRelay:%d, Constants:prechargeRelay:%s", motorController->getprechargeRelay(),paramCache.prechargeRelay, Constants::prechargeRelay); } if ( bleDigIO.mainContRelay != motorController->getmainContactorRelay() ) { bleDigIO.mainContRelay = motorController->getmainContactorRelay(); bleDigIO.doUpdate = 1; } if ( bleDigIO.coolingRelay != motorController->getCoolFan() ) { bleDigIO.coolingRelay = motorController->getCoolFan(); bleDigIO.doUpdate = 1; } if ( bleDigIO.coolOnTemp != motorController->getCoolOn() ) { bleDigIO.coolOnTemp = motorController->getCoolOn(); bleDigIO.doUpdate = 1; } if ( bleDigIO.coolOffTemp != motorController->getCoolOff() ) { bleDigIO.coolOffTemp = motorController->getCoolOff(); bleDigIO.doUpdate = 1; } if ( bleDigIO.brakeLightOut != motorController->getBrakeLight() ) { bleDigIO.brakeLightOut = motorController->getBrakeLight(); bleDigIO.doUpdate = 1; } if ( bleDigIO.reverseLightOut != motorController->getRevLight() ) { bleDigIO.reverseLightOut = motorController->getRevLight(); bleDigIO.doUpdate = 1; } if ( bleDigIO.enableIn != motorController->getEnableIn() ) { bleDigIO.enableIn = motorController->getEnableIn(); bleDigIO.doUpdate = 1; } if ( bleDigIO.reverseIn != motorController->getReverseIn() ) { bleDigIO.reverseIn = motorController->getReverseIn(); bleDigIO.doUpdate = 1; } } } else if (tickCounter > 4) { if (motorController) { //Logger::console("Wifi tick counter 5..."); if ( bleTemperatures.motorTemperature != motorController->getTemperatureMotor() ) { bleTemperatures.motorTemperature = motorController->getTemperatureMotor(); bleTemperatures.doUpdate = 1; } if ( bleTemperatures.inverterTemperature != motorController->getTemperatureInverter() ) { bleTemperatures.inverterTemperature = motorController->getTemperatureInverter(); bleTemperatures.doUpdate = 1; } if ( bleTemperatures.systemTemperature != motorController->getTemperatureSystem() ) { bleTemperatures.systemTemperature = motorController->getTemperatureSystem(); bleTemperatures.doUpdate = 1; } } tickCounter = 0; } transferUpdates(); //send out any updates required }
CXXCAPI int unittestThrottle(void) { Print printf(Platform::instance().output()); Print errorf(Platform::instance().error()); int errors = 0; Throttle throttle; Throttle save1 = throttle; Throttle save2; ticks_t delay; bool alarmed; bool ok; printf("%s[%d]: begin\n", __FILE__, __LINE__); ::staticThrottle.show(); printf("%s[%d]: constructors\n", __FILE__, __LINE__); throttle.show(); save1.show(); save2 = throttle; save2.show(); printf("%s[%d]: initial\n", __FILE__, __LINE__); throttle.show(); printf("%s[%d]: time\n", __FILE__, __LINE__); if ((delay = throttle.frequency()) != 0) { errorf("%s[%d]: (%lu!=%lu)!\n", __FILE__, __LINE__, delay, 0); throttle.show(); ++errors; } printf("%s[%d]: admissibility\n", __FILE__, __LINE__); if ((alarmed = throttle.isAlarmed())) { errorf("%s[%d]: (%d!=%d)!\n", __FILE__, __LINE__, alarmed, false); throttle.show(); ++errors; } for (int ii = 1; ii <= 5; ++ii) { if ((delay = throttle.admissible()) != 0) { errorf("%s[%d]: (%lu!=%lu)!\n", __FILE__, __LINE__, delay, 0); throttle.show(); ++errors; } if (!(ok = throttle.commit())) { errorf("%s[%d]: (%d!=%d)!\n", __FILE__, __LINE__, ok, true); throttle.show(); ++errors; } if ((alarmed = throttle.isAlarmed())) { errorf("%s[%d]: (%d!=%d)!\n", __FILE__, __LINE__, alarmed, false); throttle.show(); ++errors; } } printf("%s[%d]: final\n", __FILE__, __LINE__); throttle.show(); printf("%s[%d]: reset\n", __FILE__, __LINE__); throttle.reset(); throttle.show(); printf("%s[%d]: end errors=%d\n", __FILE__, __LINE__, errors); return errors; }
int main(int argc, char **argv) { Tossim* t = new Tossim(NULL); SerialForwarder *sf = new SerialForwarder(9001); map<int, int> motes; map<int, int>::const_iterator iter; Throttle *throttle = new Throttle(t, 1); t->init(); FILE *tables = fopen("table.txt", "w"); FILE *flows = fopen("flows.txt", "w"); //FILE *am = fopen("am.txt", "w"); //t->addChannel("Scheduler", fdopen(1, "w")); //t->addChannel("TossimPacketModelC", fdopen(1, "w")); //t->addChannel("LedsC", fdopen(1, "w")); //t->addChannel("AM", am); /* t->addChannel("Acks", stdout); */ //t->addChannel("Boot", stdout); /* t->addChannel("base", stdout); */ /* t->addChannel("printf", stdout); */ /* t->addChannel("Debug", stdout); */ /* t->addChannel("Unique", stdout); */ /* t->addChannel("SNRLoss", stdout); */ //t->addChannel("CpmModelC", stdout); //t->addChannel("PacketLink", stdout); //t->addChannel("Lqi", stdout); /* t->addChannel("Footer", stdout); */ t->addChannel("Drops", stdout); t->addChannel("Evictions", stdout); t->addChannel("Install", stdout); t->addChannel("Table", tables); t->addChannel("Flows", flows); t->addChannel("Test", stdout); /* t->addChannel("Status", stdout); */ Radio* r = t->radio(); FILE *fp = fopen(argv[1], "r"); int from, to, noise; float gain; int maxNode; while (fscanf(fp, "gain\t%i\t%i\t%f\n", &from, &to, &gain) != EOF) { r->add(from, to, gain); motes[from] = 1; motes[to] = 1; } fclose(fp); throttle->initialize(); // fp = fopen("casino-lab.txt", "r"); fp = fopen("meyer-heavy.txt", "r"); int i = 0; while(fscanf(fp,"%i\n", &noise) != EOF && i++ < 1000) { for (iter = motes.begin(); iter != motes.end(); ++iter ) { t->getNode(iter->first)->addNoiseTraceReading(noise); } } fclose(fp); for (iter = motes.begin(); iter != motes.end(); ++iter ) { printf("creating noise model for %i\n", iter->first); t->getNode(iter->first)->createNoiseModel(); } for (iter = motes.begin(); iter != motes.end(); ++iter ) { printf("booting mote %i\n", iter->first); t->getNode(iter->first)->bootAtTime((31 + t->ticksPerSecond() / 10) * iter->first + 1); } sf->process(); for (;;) { //throttle->checkThrottle(); t->runNextEvent(); sf->process(); } }
/* * Process the parameter update from ichip we received as a response to AT+iWNXT. * The response usually looks like this : key="value", so the key can be isolated * by looking for the '=' sign and the leading/trailing '"' have to be ignored. */ void ADAFRUITBLE::processParameterChange(char *key) { PotThrottleConfiguration *acceleratorConfig = NULL; PotThrottleConfiguration *brakeConfig = NULL; MotorControllerConfiguration *motorConfig = NULL; bool parameterFound = true; char *value = strchr(key, '='); if (!value) return; Throttle *accelerator = DeviceManager::getInstance()->getAccelerator(); Throttle *brake = DeviceManager::getInstance()->getBrake(); MotorController *motorController = DeviceManager::getInstance()->getMotorController(); if (accelerator) acceleratorConfig = (PotThrottleConfiguration *)accelerator->getConfiguration(); if (brake) brakeConfig = (PotThrottleConfiguration *)brake->getConfiguration(); if(motorController) motorConfig = (MotorControllerConfiguration *)motorController->getConfiguration(); value[0] = 0; // replace the '=' sign with a 0 value++; if (value[0] == '"') value++; // if the value starts with a '"', advance one character if (value[strlen(value) - 1] == '"') value[strlen(value) - 1] = 0; // if the value ends with a '"' character, replace it with 0 if (!strcmp(key, Constants::numThrottlePots) && acceleratorConfig) { acceleratorConfig->numberPotMeters = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, Constants::throttleSubType) && acceleratorConfig) { acceleratorConfig->throttleSubType = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, Constants::throttleMin1) && acceleratorConfig) { acceleratorConfig->minimumLevel1 = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, Constants::throttleMin2) && acceleratorConfig) { acceleratorConfig->minimumLevel2 = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, Constants::throttleMax1) && acceleratorConfig) { acceleratorConfig->maximumLevel1 = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, Constants::throttleMax2) && acceleratorConfig) { acceleratorConfig->maximumLevel2 = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, Constants::throttleRegenMax) && acceleratorConfig) { acceleratorConfig->positionRegenMaximum = atol(value) * 10; } else if (!strcmp(key, Constants::throttleRegenMin) && acceleratorConfig) { acceleratorConfig->positionRegenMinimum = atol(value) * 10; accelerator->saveConfiguration(); } else if (!strcmp(key, Constants::throttleFwd) && acceleratorConfig) { acceleratorConfig->positionForwardMotionStart = atol(value) * 10; accelerator->saveConfiguration(); } else if (!strcmp(key, Constants::throttleMap) && acceleratorConfig) { acceleratorConfig->positionHalfPower = atol(value) * 10; accelerator->saveConfiguration(); } else if (!strcmp(key, Constants::throttleMinRegen) && acceleratorConfig) { acceleratorConfig->minimumRegen = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, Constants::throttleMaxRegen) && acceleratorConfig) { acceleratorConfig->maximumRegen = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, Constants::throttleCreep) && acceleratorConfig) { acceleratorConfig->creep = atol(value); accelerator->saveConfiguration(); } else if (!strcmp(key, Constants::brakeMin) && brakeConfig) { brakeConfig->minimumLevel1 = atol(value); brake->saveConfiguration(); } else if (!strcmp(key, Constants::brakeMax) && brakeConfig) { brakeConfig->maximumLevel1 = atol(value); brake->saveConfiguration(); } else if (!strcmp(key, Constants::brakeMinRegen) && brakeConfig) { brakeConfig->minimumRegen = atol(value); brake->saveConfiguration(); } else if (!strcmp(key, Constants::brakeMaxRegen) && brakeConfig) { brakeConfig->maximumRegen = atol(value); brake->saveConfiguration(); } else if (!strcmp(key, Constants::speedMax) && motorConfig) { motorConfig->speedMax = atol(value); motorController->saveConfiguration(); } else if (!strcmp(key, Constants::torqueMax) && motorConfig) { motorConfig->torqueMax = atol(value) * 10; motorController->saveConfiguration(); } else if (!strcmp(key, Constants::coolFan) && motorConfig) { motorConfig->coolFan = atol(value); motorController->saveConfiguration(); } else if (!strcmp(key, Constants::coolOn) && motorConfig) { motorConfig->coolOn = (atol(value)); motorController->saveConfiguration(); } else if (!strcmp(key, Constants::coolOff) && motorConfig) { motorConfig->coolOff = (atol(value)); motorController->saveConfiguration(); } else if (!strcmp(key, Constants::prechargeR) && motorConfig) { motorConfig->prechargeR = atol(value); motorController->saveConfiguration(); } else if (!strcmp(key, Constants::prechargeRelay) && motorConfig) { motorConfig->prechargeRelay = atol(value); motorController->saveConfiguration(); } else if (!strcmp(key, Constants::nominalVolt) && motorConfig) { motorConfig->nominalVolt = (atol(value))*10; motorController->saveConfiguration(); } else if (!strcmp(key, Constants::mainContactorRelay) && motorConfig) { motorConfig->mainContactorRelay = atol(value); motorController->saveConfiguration(); } else if (!strcmp(key, Constants::brakeLight) && motorConfig) { motorConfig->brakeLight = atol(value); motorController->saveConfiguration(); } else if (!strcmp(key, Constants::revLight) && motorConfig) { motorConfig->revLight = atol(value); motorController->saveConfiguration(); } else if (!strcmp(key, Constants::enableIn) && motorConfig) { motorConfig->enableIn = atol(value); motorController->saveConfiguration(); } else if (!strcmp(key, Constants::reverseIn) && motorConfig) { motorConfig->reverseIn = atol(value); motorController->saveConfiguration(); /* } else if (!strcmp(key, Constants::motorMode) && motorConfig) { motorConfig->motorMode = (MotorController::PowerMode)atoi(value); motorController->saveConfiguration(); */ } else if (!strcmp(key, "x1000")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16),true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } //sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x1001")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16),true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } //sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x1002")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16),true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } // sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x1031")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } //sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x1032")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } //sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x1033")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } //sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x1034")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } // sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x1010")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } // sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x1011")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } //sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x1012")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } //sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x1020")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x1040")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } // sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x1050")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } // sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x2000")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x4400")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } // sysPrefs->forceCacheWrite(); sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x6000")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } // sysPrefs->forceCacheWrite(); } else if (!strcmp(key, "x650")) { if (255==atol(value)) { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), true); } else { sysPrefs->setDeviceStatus(strtol(key+1, 0, 16), false); } // sysPrefs->forceCacheWrite(); } else if (!strcmp(key, Constants::logLevel)) { extern PrefHandler *sysPrefs; uint8_t loglevel = atoi(value); Logger::setLoglevel((Logger::LogLevel)loglevel); sysPrefs->write(EESYS_LOG_LEVEL, loglevel); } else { parameterFound = false; } if (parameterFound) { Logger::info(ADABLUE, "parameter change: %s", key); } else { sysPrefs->forceCacheWrite(); DeviceManager::getInstance()->updateWifi(); } }
void MotorController::handleTick() { uint8_t forwardSwitch, reverseSwitch; MotorControllerConfiguration *config = (MotorControllerConfiguration *)getConfiguration(); gearSwitch = GS_FORWARD; if(ready) statusBitfield1 |=1 << 15;else statusBitfield1 &= ~(1 <<15); if(running) statusBitfield1 |=1 << 14;else statusBitfield1 &= ~(1 <<14); if(warning) statusBitfield1 |=1 << 10;else statusBitfield1 &= ~(1 <<10); if(faulted) statusBitfield1 |=1 << 9;else statusBitfield1 &= ~(1 <<9); mechanicalPower=dcVoltage*dcCurrent/10000; //In kilowatts. DC voltage is x10 efficiency=(speedActual*torqueActual*0.1045)/(mechanicalPower*100000); if (dcVoltage>nominalVolts && torqueActual>-10) {kiloWattHours=1;} //If our voltage is higher than fully charged with no regen, zero our kwh meter if (milliStamp>millis()) {milliStamp=0;} //In case millis rolls over to zero while running kiloWattHours+=(millis()-milliStamp)*mechanicalPower;//We assume here that power is at current level since last tick and accrue in kilowattmilliseconds. milliStamp=millis();//reset our kwms timer for next check Throttle *accelerator = DeviceManager::getInstance()->getAccelerator(); Throttle *brake = DeviceManager::getInstance()->getBrake(); if (accelerator) throttleRequested = accelerator->getLevel(); if (brake && brake->getLevel() < -10 && brake->getLevel() < accelerator->getLevel()) //if the brake has been pressed it overrides the accelerator. throttleRequested = brake->getLevel(); if (!donePrecharge && config->prechargeR>0) { if (millis()> config->prechargeR) //Check milliseconds since startup against our entered delay in milliseconds { donePrecharge=1; //Time's up. Let's don't do ANY of this on future ticks. if (config->mainContactorRelay!=255) //If we HAVE a main contactor, turn it on. { setOutput(config->mainContactorRelay, 1); //Main contactor on statusBitfield2 |=1 << 17; //set bit to turn on MAIN CONTACTOR annunciator statusBitfield1 |=1 << config->mainContactorRelay;//setbit to Turn on main contactor output annunciator //I've commented the below out to leave the precharge relay ON after precharge..see user guide for why. //setOutput(config->prechargeRelay, 0); //ok. Turn off precharge output // statusBitfield2 &= ~(1 << 19); //clearbit to turn off PRECHARGE annunciator //statusBitfield1 &= ~(1<< config->prechargeRelay); //clear bit to turn off PRECHARGE output annunciator Logger::console("Precharge sequence complete after %i milliseconds", config->prechargeR); Logger::console("MAIN CONTACTOR ENABLED...DOUT0:%d, DOUT1:%d, DOUT2:%d, DOUT3:%d,DOUT4:%d, DOUT5:%d, DOUT6:%d, DOUT7:%d", getOutput(0), getOutput(1), getOutput(2), getOutput(3),getOutput(4), getOutput(5), getOutput(6), getOutput(7)); } } else //If time is not up and maybe this is our first tick, let's set the precharge relay IF we have one //and clear the main contactor IF we have one.We'll set PRELAY so we only have to do this once. { if (config->prechargeRelay==255 || config->mainContactorRelay==255){donePrecharge=1;} if(!prelay) { if (config->prechargeRelay!=255) { setOutput(config->prechargeRelay, 1); //ok. Turn on precharge statusBitfield2 |=1 << 19; //set bit to turn on PRECHARGE RELAY annunciator statusBitfield1 |=1 << config->prechargeRelay; //set bit to turn ON precharge OUTPUT annunciator throttleRequested = 0; //Keep throttle at zero during precharge prelay=true; } if (config->mainContactorRelay!=255) { setOutput(config->mainContactorRelay, 0); //Main contactor off statusBitfield2 &= ~(1 << 17); //clear bitTurn off MAIN CONTACTOR annunciator statusBitfield1 &= ~(1 << config->mainContactorRelay);//clear bitTurn off main contactor output annunciator prelay=true; } } } } if(skipcounter++ > 30) //As how fast we turn on cooling is very low priority, we only check cooling every 24th lap or about once per second { if(config->prechargeR==12345) { dcVoltage--; temperatureInverter++; temperatureMotor++; if (torqueActual < -500) {torqueActual=20;} else {torqueActual=-650;} } coolingcheck(); prefsHandler->write(EEMC_KILOWATTHRS, kiloWattHours); //store kilowatt hours to EEPROM prefsHandler->saveChecksum(); // memCache->Write(63000,kiloWattHours); } }
/*For simplicity the configuration setting code uses four characters for each configuration choice. This makes things easier for comparison purposes. */ void SerialConsole::handleConfigCmd() { PotThrottleConfiguration *acceleratorConfig = NULL; PotThrottleConfiguration *brakeConfig = NULL; MotorControllerConfiguration *motorConfig = NULL; Throttle *accelerator = DeviceManager::getInstance()->getAccelerator(); Throttle *brake = DeviceManager::getInstance()->getBrake(); MotorController *motorController = DeviceManager::getInstance()->getMotorController(); int i; int newValue; bool updateWifi = true; //Logger::debug("Cmd size: %i", ptrBuffer); if (ptrBuffer < 6) return; //4 digit command, =, value is at least 6 characters cmdBuffer[ptrBuffer] = 0; //make sure to null terminate String cmdString = String(); unsigned char whichEntry = '0'; i = 0; while (cmdBuffer[i] != '=' && i < ptrBuffer) { cmdString.concat(String(cmdBuffer[i++])); } i++; //skip the = if (i >= ptrBuffer) { Logger::console("Command needs a value..ie TORQ=3000"); Logger::console(""); return; //or, we could use this to display the parameter instead of setting } if (accelerator) acceleratorConfig = (PotThrottleConfiguration *) accelerator->getConfiguration(); if (brake) brakeConfig = (PotThrottleConfiguration *) brake->getConfiguration(); if (motorController) motorConfig = (MotorControllerConfiguration *) motorController->getConfiguration(); // strtol() is able to parse also hex values (e.g. a string "0xCAFE"), useful for enable/disable by device id newValue = strtol((char *) (cmdBuffer + i), NULL, 0); cmdString.toUpperCase(); if (cmdString == String("TORQ") && motorConfig) { Logger::console("Setting Torque Limit to %i", newValue); motorConfig->torqueMax = newValue; motorController->saveConfiguration(); } else if (cmdString == String("RPM") && motorConfig) { Logger::console("Setting RPM Limit to %i", newValue); motorConfig->speedMax = newValue; motorController->saveConfiguration(); } else if (cmdString == String("REVLIM") && motorConfig) { Logger::console("Setting Reverse Limit to %i", newValue); motorConfig->reversePercent = newValue; motorController->saveConfiguration(); } else if (cmdString == String("TPOT") && acceleratorConfig) { Logger::console("Setting # of Throttle Pots to %i", newValue); acceleratorConfig->numberPotMeters = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("TTYPE") && acceleratorConfig) { Logger::console("Setting Throttle Subtype to %i", newValue); acceleratorConfig->throttleSubType = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("T1ADC") && acceleratorConfig) { Logger::console("Setting Throttle1 ADC pin to %i", newValue); acceleratorConfig->AdcPin1 = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("T1MN") && acceleratorConfig) { Logger::console("Setting Throttle1 Min to %i", newValue); acceleratorConfig->minimumLevel1 = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("T1MX") && acceleratorConfig) { Logger::console("Setting Throttle1 Max to %i", newValue); acceleratorConfig->maximumLevel1 = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("T2ADC") && acceleratorConfig) { Logger::console("Setting Throttle2 ADC pin to %i", newValue); acceleratorConfig->AdcPin2 = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("T2MN") && acceleratorConfig) { Logger::console("Setting Throttle2 Min to %i", newValue); acceleratorConfig->minimumLevel2 = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("T2MX") && acceleratorConfig) { Logger::console("Setting Throttle2 Max to %i", newValue); acceleratorConfig->maximumLevel2 = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("TRGNMAX") && acceleratorConfig) { Logger::console("Setting Throttle Regen maximum to %i", newValue); acceleratorConfig->positionRegenMaximum = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("TRGNMIN") && acceleratorConfig) { Logger::console("Setting Throttle Regen minimum to %i", newValue); acceleratorConfig->positionRegenMinimum = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("TFWD") && acceleratorConfig) { Logger::console("Setting Throttle Forward Start to %i", newValue); acceleratorConfig->positionForwardMotionStart = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("TMAP") && acceleratorConfig) { Logger::console("Setting Throttle MAP Point to %i", newValue); acceleratorConfig->positionHalfPower = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("TMINRN") && acceleratorConfig) { Logger::console("Setting Throttle Regen Minimum Strength to %i", newValue); acceleratorConfig->minimumRegen = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("TMAXRN") && acceleratorConfig) { Logger::console("Setting Throttle Regen Maximum Strength to %i", newValue); acceleratorConfig->maximumRegen = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("TCREEP") && acceleratorConfig) { Logger::console("Setting Throttle Creep Strength to %i", newValue); acceleratorConfig->creep = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("BMAXR") && brakeConfig) { Logger::console("Setting Max Brake Regen to %i", newValue); brakeConfig->maximumRegen = newValue; brake->saveConfiguration(); } else if (cmdString == String("BMINR") && brakeConfig) { Logger::console("Setting Min Brake Regen to %i", newValue); brakeConfig->minimumRegen = newValue; brake->saveConfiguration(); } else if (cmdString == String("B1ADC") && acceleratorConfig) { Logger::console("Setting Brake ADC pin to %i", newValue); brakeConfig->AdcPin1 = newValue; accelerator->saveConfiguration(); } else if (cmdString == String("B1MX") && brakeConfig) { Logger::console("Setting Brake Max to %i", newValue); brakeConfig->maximumLevel1 = newValue; brake->saveConfiguration(); } else if (cmdString == String("B1MN") && brakeConfig) { Logger::console("Setting Brake Min to %i", newValue); brakeConfig->minimumLevel1 = newValue; brake->saveConfiguration(); } else if (cmdString == String("PREC") && motorConfig) { Logger::console("Setting Precharge Capacitance to %i", newValue); motorConfig->kilowattHrs = newValue; motorController->saveConfiguration(); } else if (cmdString == String("PREDELAY") && motorConfig) { Logger::console("Setting Precharge Time Delay to %i milliseconds", newValue); motorConfig->prechargeR = newValue; motorController->saveConfiguration(); } else if (cmdString == String("NOMV") && motorConfig) { Logger::console("Setting fully charged voltage to %d vdc", newValue); motorConfig->nominalVolt = newValue * 10; motorController->saveConfiguration(); } else if (cmdString == String("BRAKELT") && motorConfig) { motorConfig->brakeLight = newValue; motorController->saveConfiguration(); Logger::console("Brake light output set to DOUT%i.",newValue); } else if (cmdString == String("REVLT") && motorConfig) { motorConfig->revLight = newValue; motorController->saveConfiguration(); Logger::console("Reverse light output set to DOUT%i.",newValue); } else if (cmdString == String("ENABLEIN") && motorConfig) { motorConfig->enableIn = newValue; motorController->saveConfiguration(); Logger::console("Motor Enable input set to DIN%i.",newValue); } else if (cmdString == String("REVIN") && motorConfig) { motorConfig->reverseIn = newValue; motorController->saveConfiguration(); Logger::console("Motor Reverse input set to DIN%i.",newValue); } else if (cmdString == String("MRELAY") && motorConfig) { Logger::console("Setting Main Contactor relay output to DOUT%i", newValue); motorConfig->mainContactorRelay = newValue; motorController->saveConfiguration(); } else if (cmdString == String("PRELAY") && motorConfig) { Logger::console("Setting Precharge Relay output to DOUT%i", newValue); motorConfig->prechargeRelay = newValue; motorController->saveConfiguration(); } else if (cmdString == String("ENABLE")) { if (PrefHandler::setDeviceStatus(newValue, true)) { sysPrefs->forceCacheWrite(); //just in case someone takes us literally and power cycles quickly Logger::console("Successfully enabled device.(%X, %d) Power cycle to activate.", newValue, newValue); } else { Logger::console("Invalid device ID (%X, %d)", newValue, newValue); } } else if (cmdString == String("DISABLE")) { if (PrefHandler::setDeviceStatus(newValue, false)) { sysPrefs->forceCacheWrite(); //just in case someone takes us literally and power cycles quickly Logger::console("Successfully disabled device. Power cycle to deactivate."); } else { Logger::console("Invalid device ID (%X, %d)", newValue, newValue); } } else if (cmdString == String("SYSTYPE")) { if (newValue < 5 && newValue > 0) { sysPrefs->write(EESYS_SYSTEM_TYPE, (uint8_t)(newValue)); sysPrefs->saveChecksum(); sysPrefs->forceCacheWrite(); //just in case someone takes us literally and power cycles quickly Logger::console("System type updated. Power cycle to apply."); } else Logger::console("Invalid system type. Please enter a value 1 - 4"); } else if (cmdString == String("LOGLEVEL")) { switch (newValue) { case 0: Logger::setLoglevel(Logger::Debug); Logger::console("setting loglevel to 'debug'"); break; case 1: Logger::setLoglevel(Logger::Info); Logger::console("setting loglevel to 'info'"); break; case 2: Logger::console("setting loglevel to 'warning'"); Logger::setLoglevel(Logger::Warn); break; case 3: Logger::console("setting loglevel to 'error'"); Logger::setLoglevel(Logger::Error); break; case 4: Logger::console("setting loglevel to 'off'"); Logger::setLoglevel(Logger::Off); break; } sysPrefs->write(EESYS_LOG_LEVEL, (uint8_t)newValue); sysPrefs->saveChecksum(); } else if (cmdString == String("WIREACH")) { DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)(cmdBuffer + i)); Logger::info("sent \"AT+i%s\" to WiReach wireless LAN device", (cmdBuffer + i)); DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DOWN"); updateWifi = false; } else if (cmdString == String("SSID")) { String cmdString = String(); cmdString.concat("WLSI"); cmdString.concat('='); cmdString.concat((char *)(cmdBuffer + i)); Logger::info("Sent \"%s\" to WiReach wireless LAN device", (cmdString.c_str())); DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)cmdString.c_str()); DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DOWN"); updateWifi = false; } else if (cmdString == String("IP")) { String cmdString = String(); cmdString.concat("DIP"); cmdString.concat('='); cmdString.concat((char *)(cmdBuffer + i)); Logger::info("Sent \"%s\" to WiReach wireless LAN device", (cmdString.c_str())); DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)cmdString.c_str()); DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DOWN"); updateWifi = false; } else if (cmdString == String("CHANNEL")) { String cmdString = String(); cmdString.concat("WLCH"); cmdString.concat('='); cmdString.concat((char *)(cmdBuffer + i)); Logger::info("Sent \"%s\" to WiReach wireless LAN device", (cmdString.c_str())); DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)cmdString.c_str()); DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DOWN"); updateWifi = false; } else if (cmdString == String("SECURITY")) { String cmdString = String(); cmdString.concat("WLPP"); cmdString.concat('='); cmdString.concat((char *)(cmdBuffer + i)); Logger::info("Sent \"%s\" to WiReach wireless LAN device", (cmdString.c_str())); DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)cmdString.c_str()); DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DOWN"); updateWifi = false; } else if (cmdString == String("PWD")) { String cmdString = String(); cmdString.concat("WPWD"); cmdString.concat('='); cmdString.concat((char *)(cmdBuffer + i)); Logger::info("Sent \"%s\" to WiReach wireless LAN device", (cmdString.c_str())); DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)cmdString.c_str()); DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_COMMAND, (void *)"DOWN"); updateWifi = false; } else if (cmdString == String("COOLFAN") && motorConfig) { Logger::console("Cooling fan output updated to: %i", newValue); motorConfig->coolFan = newValue; motorController->saveConfiguration(); } else if (cmdString == String("COOLON")&& motorConfig) { if (newValue <= 200 && newValue >= 0) { Logger::console("Cooling fan ON temperature updated to: %i degrees", newValue); motorConfig->coolOn = newValue; motorController->saveConfiguration(); } else Logger::console("Invalid cooling ON temperature. Please enter a value 0 - 200F"); } else if (cmdString == String("COOLOFF")&& motorConfig) { if (newValue <= 200 && newValue >= 0) { Logger::console("Cooling fan OFF temperature updated to: %i degrees", newValue); motorConfig->coolOff = newValue; motorController->saveConfiguration(); } else Logger::console("Invalid cooling OFF temperature. Please enter a value 0 - 200F"); } else if (cmdString == String("OUTPUT") && newValue<8) { int outie = getOutput(newValue); Logger::console("DOUT%d, STATE: %d",newValue, outie); if(outie) { setOutput(newValue,0); motorController->statusBitfield1 &= ~(1 << newValue);//Clear } else { setOutput(newValue,1); motorController->statusBitfield1 |=1 << newValue;//setbit to Turn on annunciator } Logger::console("DOUT0:%d, DOUT1:%d, DOUT2:%d, DOUT3:%d, DOUT4:%d, DOUT5:%d, DOUT6:%d, DOUT7:%d", getOutput(0), getOutput(1), getOutput(2), getOutput(3), getOutput(4), getOutput(5), getOutput(6), getOutput(7)); } else if (cmdString == String("NUKE")) { if (newValue == 1) { //write zero to the checksum location of every device in the table. //Logger::console("Start of EEPROM Nuke"); uint8_t zeroVal = 0; for (int j = 0; j < 64; j++) { memCache->Write(EE_DEVICES_BASE + (EE_DEVICE_SIZE * j), zeroVal); memCache->FlushAllPages(); } Logger::console("Device settings have been nuked. Reboot to reload default settings"); } } else { Logger::console("Unknown command"); updateWifi = false; } // send updates to ichip wifi if (updateWifi) DeviceManager::getInstance()->sendMessage(DEVICE_WIFI, ICHIP2128, MSG_CONFIG_CHANGE, NULL); }
void MotorController::handleTick() { MotorControllerConfiguration *config = (MotorControllerConfiguration *)getConfiguration(); //Set status annunciators if(ready) statusBitfield1 |=1 << 15;else statusBitfield1 &= ~(1 <<15); if(running) statusBitfield1 |=1 << 14;else statusBitfield1 &= ~(1 <<14); if(warning) statusBitfield1 |=1 << 10;else statusBitfield1 &= ~(1 <<10); if(faulted) statusBitfield1 |=1 << 9;else statusBitfield1 &= ~(1 <<9); //Calculate killowatts and kilowatt hours mechanicalPower=dcVoltage*dcCurrent/10000; //In kilowatts. DC voltage is x10 if (dcVoltage>nominalVolts && torqueActual>0) {kiloWattHours=1;} //If our voltage is higher than fully charged with no regen, zero our kwh meter if (milliStamp>millis()) {milliStamp=0;} //In case millis rolls over to zero while running kiloWattHours+=(millis()-milliStamp)*mechanicalPower;//We assume here that power is at current level since last tick and accrue in kilowattmilliseconds. milliStamp=millis(); //reset our kwms timer for next check //Throttle check Throttle *accelerator = DeviceManager::getInstance()->getAccelerator(); Throttle *brake = DeviceManager::getInstance()->getBrake(); if (accelerator) throttleRequested = accelerator->getLevel(); if (brake && brake->getLevel() < -10 && brake->getLevel() < accelerator->getLevel()) //if the brake has been pressed it overrides the accelerator. throttleRequested = brake->getLevel(); //Logger::debug("Throttle: %d", throttleRequested); if (!donePrecharge)checkPrecharge(); if(skipcounter++ > 30) //A very low priority loop for checks that only need to be done once per second. { skipcounter=0; //Reset our laptimer //Some test simulations if precharge time is set to 12345 if(config->prechargeR==12345) { dcVoltage--; if (torqueActual < -500) { torqueActual=20; } else { torqueActual=-650; } if (dcCurrent < 0) { dcCurrent=120; } else { dcCurrent=-65; } if (temperatureInverter < config->coolOn*10) { temperatureInverter=(config->coolOn+2)*10; } else { temperatureInverter=(config->coolOff-2)*10; } if (throttleRequested < 500) { throttleRequested=500; } else { throttleRequested=0; } if(testenableinput) { testenableinput=false; } else { testenableinput=true; } if(testreverseinput) { testreverseinput=false; } else { testreverseinput=true; } } coolingcheck(); checkBrakeLight(); checkEnableInput(); checkReverseInput(); checkReverseLight(); //Store kilowatt hours, but only once in awhile. prefsHandler->write(EEMC_KILOWATTHRS, kiloWattHours); prefsHandler->saveChecksum(); } }
/* * Get parameters from devices and forward them to ichip. * This is required to initially set-up the ichip */ void ADAFRUITBLE::loadParameters() { MotorController *motorController = DeviceManager::getInstance()->getMotorController(); Throttle *accelerator = DeviceManager::getInstance()->getAccelerator(); Throttle *brake = DeviceManager::getInstance()->getBrake(); PotThrottleConfiguration *acceleratorConfig = NULL; PotThrottleConfiguration *brakeConfig = NULL; MotorControllerConfiguration *motorConfig = NULL; Logger::info("loading config params to adafruit ble"); //DeviceManager::getInstance()->updateWifi(); if (accelerator) acceleratorConfig = (PotThrottleConfiguration *)accelerator->getConfiguration(); if (brake) brakeConfig = (PotThrottleConfiguration *)brake->getConfiguration(); if (motorController) motorConfig = (MotorControllerConfiguration *)motorController->getConfiguration(); if (acceleratorConfig) { bleThrottleIO.numThrottlePots = acceleratorConfig->numberPotMeters; bleThrottleIO.throttleType = acceleratorConfig->throttleSubType; bleThrottleIO.throttle1Min = acceleratorConfig->minimumLevel1; bleThrottleIO.throttle2Min = acceleratorConfig->minimumLevel2; bleThrottleIO.throttle1Max = acceleratorConfig->maximumLevel1; bleThrottleIO.throttle2Max = acceleratorConfig->maximumLevel2; bleThrottleIO.doUpdate = 1; bleThrottleMap.throttleRegenMax = acceleratorConfig->positionRegenMaximum; bleThrottleMap.throttleRegenMin = acceleratorConfig->positionRegenMinimum; bleThrottleMap.throttleFwd = acceleratorConfig->positionForwardMotionStart; bleThrottleMap.throttleMap = acceleratorConfig->positionHalfPower; bleThrottleMap.throttleLowestRegen = acceleratorConfig->minimumRegen; bleThrottleMap.throttleHighestRegen = acceleratorConfig->maximumRegen; bleThrottleMap.throttleCreep = acceleratorConfig->creep; bleThrottleMap.doUpdate = 1; } if (brakeConfig) { bleBrakeParam.brakeMin = brakeConfig->minimumLevel1; bleBrakeParam.brakeMax = brakeConfig->maximumLevel1; bleBrakeParam.brakeRegenMin = brakeConfig->minimumRegen; bleBrakeParam.brakeRegenMax = brakeConfig->maximumRegen; bleBrakeParam.doUpdate = 1; } if (motorConfig) { bleDigIO.coolingRelay = motorConfig->coolFan; bleDigIO.coolOnTemp = motorConfig->coolOn; bleDigIO.coolOffTemp = motorConfig->coolOff; bleDigIO.brakeLightOut = motorConfig->brakeLight; bleDigIO.reverseLightOut = motorConfig->revLight; bleDigIO.enableIn = motorConfig->enableIn; bleDigIO.reverseIn = motorConfig->reverseIn; bleDigIO.prechargeDuration = motorConfig->prechargeR; bleDigIO.prechargeRelay = motorConfig->prechargeRelay; bleDigIO.mainContRelay = motorConfig->mainContactorRelay; bleDigIO.doUpdate = 1; bleMaxParams.nomVoltage = motorConfig->nominalVolt; bleMaxParams.maxTorque = motorConfig->torqueMax; bleMaxParams.maxRPM = motorConfig->speedMax; bleMaxParams.doUpdate = 1; } bleModes.logLevel = (uint8_t)Logger::getLogLevel(); bleModes.doUpdate = 1; transferUpdates(); }