| … | … | @@ -53,6 +53,7 @@ int ledChannel11 = 11; |
| 53 | 53 | const int PWMPins[] = {32, 33, 25, 26, 27, 14, 12, 13, 2, 23, 22, 21}; |
| 54 | 54 | const int NumPWMPins = sizeof(PWMPins) / sizeof(*PWMPins); |
| 55 | 55 | int PinCurrentValues[NumPWMPins] = {0}; |
| 56 | |
| 56 | 57 | // this flag will invert PWM output (65535 - PWM), for active-low devices |
| 57 | 58 | |
| 58 | 59 | const char *MsgPWMTupleFormatError = "Error: takes up to 6 arguments between 0 and 255"; |
| … | … | @@ -69,6 +70,7 @@ int parseListOfIDs(int *outIDs, int maxIDs); |
| 69 | 70 | void cmdUnrecognized(const char *cmd); |
| 70 | 71 | void cmdSetFrequency(); |
| 71 | 72 | void cmdPWMPins(); |
| 73 | void cmdPWMPins2(); |
| 72 | 74 | void cmdSetPrintLevel(); |
| 73 | 75 | void cmdServo(); |
| 74 | 76 | |
| … | … | @@ -76,6 +78,7 @@ SerialCommand::Entry CommandsList[] = { |
| 76 | 78 | {"plevel", cmdSetPrintLevel}, |
| 77 | 79 | {"freq", cmdSetFrequency}, |
| 78 | 80 | {"pwm", cmdPWMPins}, |
| 81 | {"pwm2", cmdPWMPins2}, |
| 79 | 82 | {"s", cmdServo}, |
| 80 | 83 | {NULL, NULL} |
| 81 | 84 | }; |
| … | … | @@ -235,6 +238,81 @@ void cmdSetFrequency() { |
| 235 | 238 | printlnAck(freq); |
| 236 | 239 | } |
| 237 | 240 | |
| 241 | void cmdPWMPins2() { |
| 242 | const char *SetPWM2UsageMsg = "Error: takes up to 13 arguments between 0 and 65535 (except argument 3's max is 45000)."; |
| 243 | |
| 244 | long channelValues[NumPWMPins]; |
| 245 | int count = 0; |
| 246 | |
| 247 | char *arg = CmdMgr.next(); |
| 248 | if (arg == NULL) { |
| 249 | printlnError("Error: no arguments"); |
| 250 | return; |
| 251 | } |
| 252 | |
| 253 | long numPeriods = parsePWM(arg, 100); |
| 254 | arg = CmdMgr.next(); |
| 255 | long periodLength = parsePWM(arg, 100); |
| 256 | arg = CmdMgr.next(); |
| 257 | |
| 258 | do { |
| 259 | int index; |
| 260 | long value; |
| 261 | |
| 262 | if (count >= NumPWMPins) { |
| 263 | printlnError(SetPWM2UsageMsg); |
| 264 | return; |
| 265 | } |
| 266 | |
| 267 | char *end; |
| 268 | index = count; |
| 269 | value = parsePWM(arg, count % 3 == 2 ? RED_MAX_PWM : MAX_PWM); |
| 270 | if (value < 0) { |
| 271 | printlnError(SetPWM2UsageMsg); |
| 272 | // value = 4000; |
| 273 | return; |
| 274 | } |
| 275 | |
| 276 | //printInfo("Set pin "); |
| 277 | //printInfo(PWMPins[index]); |
| 278 | //printInfo(" to "); |
| 279 | //printlnInfo(value); |
| 280 | channelValues[index] = value; |
| 281 | count++; |
| 282 | } while (arg = CmdMgr.next()); |
| 283 | |
| 284 | // interpolate over a period of time |
| 285 | const TickType_t xDelay = periodLength / portTICK_PERIOD_MS; |
| 286 | |
| 287 | float frameDelay = 9.14; // 9.14ms - length of time between frames at 60fps |
| 288 | |
| 289 | long beginTime = micros(); |
| 290 | long endTime = beginTime + 9140; |
| 291 | |
| 292 | for (long period = 1; period < 1+numPeriods; period++) { |
| 293 | //long beginTime = millis(); |
| 294 | float fraction = period / (float)numPeriods; |
| 295 | for (int i = 0; i < count; i++) { |
| 296 | unsigned long v = PinCurrentValues[i] + (channelValues[i] - PinCurrentValues[i]) * fraction; |
| 297 | //printlnAlways(v); |
| 298 | myHRWrite(PWMPins[i], v); |
| 299 | } |
| 300 | //long endTime = millis(); |
| 301 | //printlnAlways(endTime - beginTime); |
| 302 | //vTaskDelay(xDelay); |
| 303 | } |
| 304 | |
| 305 | for (int i = 0; i < count; i++) { |
| 306 | unsigned long v = channelValues[i]; |
| 307 | PinCurrentValues[i] = v; |
| 308 | myHRWrite(PWMPins[i], v); |
| 309 | } |
| 310 | |
| 311 | //printAck("OK set "); |
| 312 | //printAck(count); |
| 313 | //printlnAck(" pins"); |
| 314 | } |
| 315 | |
| 238 | 316 | // expects space-delimited ints 0-65535, or space delimited <index>:<pwm> pairs |
| 239 | 317 | void cmdPWMPins() { |
| 240 | 318 | const char *SetPWMUsageMsg = "Error: takes up to 12 arguments between 0 and 65535 (except argument 3's max is 45000)."; |