void IOconfig(void) // assign pins for each finger, store pins within list and set as INPUT/OUTPUT { // assign/attach finger and muscle pins pinAssignment(); // enable/disable motors for (int i = 0; i<NUM_FINGERS; i++) { if (advancedSettings.motorEnable) finger[i].enableMotor(); else finger[i].disableMotor(); } #ifdef USE_I2C_ADC // if using I2C over the headphone port, pull the SCL and SDA high using A6 & A7, as they are connected via 10k pullups pinMode(A6,OUTPUT); pinMode(A7,OUTPUT); digitalWrite(A6,HIGH); digitalWrite(A7,HIGH); ADC2.begin(); // initialise I2C_ADC for muscle sensing #else pinMode(musclePins[0],INPUT); // if using standard ADC, config pins pinMode(musclePins[1],INPUT); #endif }
/*---------------------------------------- * * Start the massive Gcode processing loop *----------------------------------------- */ void process_commands() { int result; int motorChannel, motorPower; unsigned long codenum; char *starpos = NULL; if(code_seen('G')) { switch((int)code_value()) { case 0: // G0 -> G1 case 1: // G1 break; case 2: break; case 3: break; case 4: // G4 dwell //LCD_MESSAGEPGM(MSG_DWELL); codenum = 0; if(code_seen('P')) codenum = code_value(); // milliseconds to wait if(code_seen('S')) codenum = code_value() * 1000; // seconds to wait //codenum += millis(); // keep track of when we started waiting previous_millis_cmd = 0;//millis(); while(++previous_millis_cmd < codenum ){ manage_inactivity(); _delay_ms(1); } break; case 5: // G5 - Absolute command motor C<Channel> P<motor power -1000 to 1000> if(!Stopped) { if(code_seen('C')) { motorChannel = code_value(); // motor channel 1,2 if(code_seen('P')) { motorPower = code_value(); // motor power -1000,1000 fault = 0; // clear fault flag motorControl->commandMotorPower(motorChannel, motorPower); } // code P } // code C } // stopped break; case 28: previous_millis_cmd = 0; break; case 90: // G90 break; case 91: // G91 break; case 92: // G92 break; case 99: // G99 start watchdog timer. G99 T<time_in_millis> values are 15,30,60,120,250,500,1000,4000,8000 default 4000 if( code_seen('T') ) { int time_val = code_value(); watchdog_timer = new WatchdogTimer(); watchdog_timer->watchdog_init(time_val); } break; case 100: // G100 reset watchog timer before time interval is expired, otherwise a reset occurs if( watchdog_timer != NULL ) watchdog_timer->watchdog_reset(); break; } // switch } // if code /*------------------------------------- * M Code processing *-------------------------------------- */ else if(code_seen('M')) { switch( (int)code_value() ) { case 0: // M0 Set real time output off realtime_output = 0; break; case 1: // M1 Set real time output on realtime_output = 1; break; case 2: // M2 [C<channel> E<encoder pin>] set smart controller (default) with optional encoder pin per channel motor_status = 0; motorControl = &roboteqDevice; if(code_seen('C')) { channel = code_value(); if(code_seen('E')) { pin_number = code_value(); motorControl->createEncoder(channel, pin_number); } } break; //Set PWM motor driver, map pin to channel, this will check to prevent free running motors during inactivity //For a PWM motor control subsequent G5 commands are affected here. case 3: // M3 P<pin> C<channel> D<direction pin> E<default dir> W<encoder pin> [T<timer mode 0-3>] [R<resolution 8,9,10 bits>] [X<prescale 0-7>] motor_status = 1; pin_number = -1; encode_pin = 0; motorControl = (AbstractMotorControl*)&hBridgeDriver; ((HBridgeDriver*)motorControl)->setMotors((PWM**)&ppwms); ((HBridgeDriver*)motorControl)->setDirectionPins((Digital**)&pdigitals); if(code_seen('P')) pin_number = code_value(); else break; if(code_seen('C')) { channel = code_value(); if( code_seen('D')) dir_pin = code_value(); else break; if( code_seen('E')) dir_default = code_value(); else break; if( code_seen('W')) encode_pin = code_value(); ((HBridgeDriver*)motorControl)->createPWM(channel, pin_number, dir_pin, dir_default, timer_pre, timer_res); if(encode_pin) motorControl->createEncoder(channel, encode_pin); } // code C break; case 4: // BLDC motor // BLDC: lo1,lo2,lo3,hi1,hi2,hi3,hall1,hall2,hall3,enable // hall sensors hall1:bit0,hall2:bit1,hall2:bit2 of commu array offset // BLDC3PhaseSensor* tmotor1 = new BLDC3PhaseSensor(29,31,33,8,9,10,64,65,66); // tmotor2 = new BLDC3PhaseSensor(35,37,39,11,12,13,67,68,69,30); // tmotor1->motor_init(); // tmotor2->Motor_init(); break; case 11: // M11 C<channel> D<duration> Set maximum motor cycle duration for given channel. if( code_seen('C') ) { channel = code_value(); if( code_seen('D') ) motorControl->setDuration(channel, code_value()); } break; case 12: // M12 C<channel> P<offset> set amount to add to G5 for min motor power if( code_seen('C') ) { channel = code_value(); if( code_seen('P')) motorControl->setMinMotorPower(channel, code_value()); } break; case 17: break; case 18: //M18 break; case 31: //M31 take time since the start of the SD print or an M109 command stoptime=0;//millis(); char time[30]; t =(stoptime-starttime)/1000; int sec,min; min=t/60; sec=t%60; sprintf_P(time, PSTR("%i min, %i sec"), min, sec); SERIAL_PGMLN(timeCntrlHdr); SERIAL_PGM("1 "); SERIAL_PORT.println(time); SERIAL_PORT.flush(); //lcd_setstatus(time); //autotempShutdown(); break; case 33: // M33 P<ultrasonic pin> D<min. distance in cm> [E<direction 1- forward facing, 0 - reverse facing sensor>] // link Motor controller to ultrasonic sensor, the sensor must exist via M301 motor_status = 1; pin_number = 0; if(code_seen('P')) { pin_number = code_value(); if( code_seen('D')) dist = code_value(); else break; dir_face = 1; // default forward if( code_seen('E')) dir_face = code_value(); // optional motorControl->linkDistanceSensor((Ultrasonic**)psonics, pin_number, dist, dir_face); } // code_seen = 'P' break; case 35: //M35 - Clear all digital pins for(int i = 0; i < 10; i++) { if(pdigitals[i]) { unassignPin(pdigitals[i]->pin); delete pdigitals[i]; pdigitals[i] = 0; } } break; case 36: //M36 - Clear all analog pins for(int i = 0; i < 10; i++) { if(panalogs[i]) { unassignPin(panalogs[i]->pin); delete panalogs[i]; panalogs[i] = 0; } } break; case 37: //M36 - Clear all PWM pins for(int i = 0; i < 10; i++) { if(ppwms[i]) { unassignPin(ppwms[i]->pin); delete ppwms[i]; ppwms[i] = 0; } } break; case 38: //M38 - Remove PWM pin P<pin> pin_number = -1; if (code_seen('P')) { pin_number = code_value(); if(unassignPin(pin_number) ) { for(int i = 0; i < 10; i++) { if(ppwms[i] && ppwms[i]->pin == pin_number) { delete ppwms[i]; ppwms[i] = 0; } // pwms == pin_number } // i iterate pwm array } // unassign pin } // code P break; case 39: //M39 - Remove Persistent Analog pin P<pin> pin_number = -1; if (code_seen('P')) { pin_number = code_value(); if(unassignPin(pin_number) ) { for(int i = 0; i < 10; i++) { if(panalogs[i] && panalogs[i]->pin == pin_number) { delete panalogs[i]; panalogs[i] = 0; break; } } } } break; case 40: //M40 - Remove persistent digital pin P<pin> pin_number = -1; if (code_seen('P')) { pin_number = code_value(); if(unassignPin(pin_number) ) { for(int i = 0; i < 10; i++) { if(pdigitals[i] && pdigitals[i] == pin_number) { delete pdigitals[i]; pdigitals[i] = 0; break; } } } } break; case 41: //M41 - Create persistent digital pin, Write digital pin HIGH P<pin> (this gives you a 5v source on pin) pin_number = -1; if (code_seen('P')) { pin_number = code_value(); if( assignPin(pin_number) ) { dpin = new Digital(pin_number); dpin->setPin(pin_number); dpin->pinMode(OUTPUT); dpin->digitalWrite(HIGH); for(int i = 0; i < 10; i++) { if(!pdigitals[i]) { pdigitals[i] = dpin; break; } } } else { for(int i = 0; i < 10; i++) { if(pdigitals[i] && pdigitals[i]->pin == pin_number) { pdigitals[i]->setPin(pin_number); pdigitals[i]->pinMode(OUTPUT); pdigitals[i]->digitalWrite(HIGH); break; } } } } break; case 42: //M42 - Create persistent digital pin, Write digital pin LOW P<pin> (This gives you a grounded pin) pin_number = -1; if (code_seen('P')) { pin_number = code_value(); if( assignPin(pin_number) ) { dpin = new Digital(pin_number); dpin->pinMode(OUTPUT); dpin->digitalWrite(LOW); for(int i = 0; i < 10; i++) { if(!pdigitals[i]) { pdigitals[i] = dpin; break; } } } else { for(int i = 0; i < 10; i++) { if(pdigitals[i] && pdigitals[i]->pin == pin_number) { pdigitals[i]->setPin(pin_number); pdigitals[i]->pinMode(OUTPUT); pdigitals[i]->digitalWrite(LOW); break; } } } } break; case 43: // M43 Read from digital pin P<pin> pin_number = -1; if (code_seen('P')) pin_number = code_value(); if( assignPin(pin_number) ) { dpin = new Digital(pin_number); dpin->pinMode(INPUT); int res = dpin->digitalRead(); delete &dpin; unassignPin(pin_number); // reset it since this is a one-shot SERIAL_PGMLN(digitalPinHdr); SERIAL_PGM("1 "); SERIAL_PORT.println(pin_number); SERIAL_PGM("2 "); SERIAL_PORT.println(res); SERIAL_PORT.println(); SERIAL_PORT.flush(); } break; case 44: // M44 -Read digital pin with pullup P<pin> pin_number = -1; if (code_seen('P')) pin_number = code_value(); if( assignPin(pin_number) ) { dpin = new Digital(pin_number); dpin->pinMode(INPUT_PULLUP); int res = dpin->digitalRead(); delete &dpin; unassignPin(pin_number); // reset it since this is a one-shot SERIAL_PGMLN(digitalPinHdr); SERIAL_PGM("1 "); SERIAL_PORT.println(pin_number); SERIAL_PGM("2 "); SERIAL_PORT.println(res); SERIAL_PORT.flush(); } break; // PWM value between 0 and 255, default timer mode is 2; clear on match, default resolution is 8 bits, default prescale is 1 // Prescale: 1,2,4,6,7,8,9 = none, 8, 64, 256, 1024, external falling, external rising // Use M445 to disable pin permanently or use timer more 0 to stop pulse without removing pin assignment case 45: // M45 - set up PWM P<pin> S<power val 0-255> [T<timer mode 0-3>] [R<resolution 8,9,10 bits>] [X<prescale 0-7>] pin_number = -1; if(code_seen('P') ) pin_number = code_value(); else break; if (code_seen('S')) { int pin_status = code_value(); int timer_mode = 2; int timer_res = 8; int timer_pre = 1; if( pin_status < 0 || pin_status > 255) pin_status = 0; // this is a semi-permanent pin assignment so dont add if its already assigned if( assignPin(pin_number) ) { // timer mode 0-3: 0 stop, 1 toggle on compare match, 2 clear on match, 3 set on match (see HardwareTimer) if( code_seen('T') ) { timer_mode = code_value(); if( timer_mode < 0 || timer_mode > 3 ) timer_mode = 0; } // timer bit resolution 8,9, or 10 bits if( code_seen('R')) { timer_res = code_value(); if( timer_res < 8 || timer_res > 10 ) timer_res = 8; } // X - prescale 0-7 for power of 2 if( code_seen('X') ) { timer_pre = code_value(); if( timer_pre < 0 || timer_pre > 7 ) timer_pre = 0; } for(int i = 0; i < 10; i++) { if(ppwms[i] == NULL) { ppin = new PWM(pin_number); ppin->init(pin_number); ppin->setPWMPrescale(timer_pre); ppin->setPWMResolution(timer_res); ppin->pwmWrite(pin_status,timer_mode); // default is 2, clear on match. to turn off, use 0 ppwms[i] = ppin; break; } } } else { // reassign pin with new mode and value for(int i = 0; i < 10; i++) { if(ppwms[i] && ppwms[i]->pin == pin_number) { // timer mode 0-3: 0 stop, 1 toggle on compare match, 2 clear on match, 3 set on match (see HardwareTimer) if( code_seen('T') ) { timer_mode = code_value(); if( timer_mode < 0 || timer_mode > 3 ) timer_mode = 2; // mess up the code get clear on match default } //ppwms[i]->init(); ppwms[i]->pwmWrite(pin_status, timer_mode); break; } } } } break; case 46: // M46 -Read analog pin P<pin> pin_number = -1; if (code_seen('P')) pin_number = code_value(); if( assignPin(pin_number) ) { apin = new Analog(pin_number); int res = apin->analogRead(); res = apin->analogRead(); // de-jitter delete &apin; unassignPin(pin_number); SERIAL_PGMLN(analogPinHdr); SERIAL_PGM("1 "); SERIAL_PORT.println(pin_number); SERIAL_PGM("2 "); SERIAL_PORT.println(res); SERIAL_PORT.flush(); } break; case 80: // M80 - Turn on Power Supply #if defined(PS_ON_PIN) && PS_ON_PIN > -1 SET_OUTPUT(PS_ON_PIN); //GND WRITE(PS_ON_PIN, PS_ON_AWAKE); // If you have a switch on suicide pin, this is useful #if defined(SUICIDE_PIN) && SUICIDE_PIN > -1 SET_OUTPUT(SUICIDE_PIN); WRITE(SUICIDE_PIN, HIGH); #endif #endif break; case 81: // M81 - Turn off Power if( motorControl->isConnected()) motorControl->commandEmergencyStop(); #if defined(SUICIDE_PIN) && SUICIDE_PIN > -1 suicide(); #elif defined(PS_ON_PIN) && PS_ON_PIN > -1 SET_OUTPUT(PS_ON_PIN); WRITE(PS_ON_PIN, PS_ON_ASLEEP); #endif _delay_ms(1000); // Wait 1 sec before switch off break; case 82: break; case 83: break; case 84: // M84 break; case 85: // M85 break; case 92: // M92 break; case 104: // M104 break; case 105 : // M105 SERIAL_PORT.println(); break; case 106: //M106 break; case 107: //M107 break; case 109: // M109 break; case 115: // M115 SERIAL_PGMLN(MSG_M115_REPORT); break; case 117: break; case 114: // M114 break; case 120: // M120 break; case 121: // M121 break; case 119: // M119 break; case 140: // M140 break; case 150: // M150 - set an RGB value byte red; byte grn; byte blu; if(code_seen('R')) red = code_value(); if(code_seen('U')) grn = code_value(); if(code_seen('B')) blu = code_value(); //SendColors(red,grn,blu); break; case 190: // M190 break; case 200: break; case 201: // M201 //reset_acceleration_rates(); break; case 202: // M202 break; case 203: break; case 204: // M204 acceleration T if(code_seen('T')) ;//max_acceleration = code_value(); break; case 205: //M205 advanced settings: maximum travel speed T=travel if(code_seen('T')) ;//maxtravelspeed = code_value(); break; case 206: break; case 207: break; case 208: break; case 209: break; case 218: break; case 220: if(code_seen('S')) { } break; case 221: if(code_seen('S')) { } break; case 226: // M226 P<pin number> S<pin state>- Wait until the specified pin reaches the state required, default is opposite current state if(code_seen('P')) { int pin_number = code_value(); // pin number int pin_state = -1; // required pin state - default is inverted if(code_seen('S')) pin_state = code_value(); // required pin state if( assignPin(pin_number) ) { Digital pn = new Digital(pin_number); pn.pinMode(INPUT); int target; switch(pin_state){ case 1: target = HIGH; break; case 0: target = LOW; break; default: target = !pn.digitalRead(); // opposite of current state break; } // switch while(pn.digitalRead() != target) { manage_inactivity(); } // while delete &pn; unassignPin(pin_number); } // if pin_number } // code seen p break; case 227: // M227 P<pin number> S<pin state>- INPUT_PULLUP Wait until the specified pin reaches the state required, default is opposite current state if(code_seen('P')) { int pin_number = code_value(); // pin number int pin_state = -1; // required pin state - default is inverted if(code_seen('S')) pin_state = code_value(); // required pin state if( assignPin(pin_number) ) { Digital pn = new Digital(pin_number); pn.pinMode(INPUT_PULLUP); int target; switch(pin_state){ case 1: target = HIGH; break; case 0: target = LOW; break; default: target = !pn.digitalRead(); // opposite of current state break; } // switch while(pn.digitalRead() != target) { manage_inactivity(); } // while delete &pn; unassignPin(pin_number); } // if pin_number } // code seen p break; case 240: // M240 Triggers a camera by emulating a Canon RC-1 : http://www.doc-diy.net/photo/rc-1_hacked/ /* #if defined(PHOTOGRAPH_PIN) && PHOTOGRAPH_PIN > -1 const uint8_t NUM_PULSES=16; const float PULSE_LENGTH=0.01524; for(int i=0; i < NUM_PULSES; i++) { WRITE(PHOTOGRAPH_PIN, HIGH); _delay_ms(PULSE_LENGTH); WRITE(PHOTOGRAPH_PIN, LOW); _delay_ms(PULSE_LENGTH); } delay(7.33); for(int i=0; i < NUM_PULSES; i++) { WRITE(PHOTOGRAPH_PIN, HIGH); _delay_ms(PULSE_LENGTH); WRITE(PHOTOGRAPH_PIN, LOW); _delay_ms(PULSE_LENGTH); } #endif */ break; case 250: break; case 280: break; case 300: // M300 - emit ultrasonic pulse on given pin and return duration P<pin number> uspin = code_seen('P') ? code_value() : 0; if (uspin > 0) { Ultrasonic* upin = new Ultrasonic(uspin); pin_number = upin->getPin(); SERIAL_PGMLN(sonicCntrlHdr); SERIAL_PGM("1 "); // pin SERIAL_PORT.println(pin_number); SERIAL_PGM("2 "); // sequence SERIAL_PORT.println(upin->getRange()); // range delete upin; } break; case 301: // M301 - toggle ultrasonic during inactivity P<pin> // wont assign pin 0 as its sensitive uspin = code_seen('P') ? code_value() : 0; // this is a permanent pin assignment so dont add if its already assigned if( assignPin(uspin) ) { for(int i = 0; i < 10; i++) { if(!psonics[i]) { psonics[i] = new Ultrasonic(uspin); break; } } } break; case 302: // M302 - disable ultrasonic during inactivity P<pin> uspin = code_seen('P') ? code_value() : 0; unassignPin(uspin); for(int i = 0; i < 10; i++) { if(psonics[i] && psonics[i] == uspin) { delete psonics[i]; psonics[i] = 0; break; } } break; case 303: // M303 - toggle analog read during inactivity P<pin> with exclusion range 0-1024 via L<min> H<max> if present // wont assign pin 0 as its sensitive // if optional L and H values exclude readings in that range uspin = code_seen('P') ? code_value() : 0; // this is a permanent pin assignment so dont add if its already assigned if( assignPin(uspin) ) { for(int i = 0; i < 10; i++) { if(!panalogs[i]) { analogRanges[0][i] = code_seen('L') ? code_value() : 0; analogRanges[1][i] = code_seen('H') ? code_value() : 0; panalogs[i] = new Analog(uspin); panalogs[i]->pinMode(INPUT); break; } } } else { // reassign values for assigned pin for(int i = 0; i < 10; i++) { if(panalogs[i] && panalogs[i]->pin == uspin) { analogRanges[0][i] = code_seen('L') ? code_value() : 0; analogRanges[1][i] = code_seen('H') ? code_value() : 0; break; } } } break; case 304:// M304 - toggle analog read INPUT_PULLUP during inactivity P<pin> with exclusion range 0-1024 via L<min> H<max> if present // if optional L and H values exclude readings in that range uspin = code_seen('P') ? code_value() : 0; // this is a permanent pin assignment so dont add if its already assigned if( assignPin(uspin) ) { for(int i = 0; i < 10; i++) { if(!panalogs[i]) { analogRanges[0][i] = code_seen('L') ? code_value() : 0; analogRanges[1][i] = code_seen('H') ? code_value() : 0; panalogs[i] = new Analog(uspin); panalogs[i]->pinMode(INPUT_PULLUP); break; } } } else { // reassign values for assigned pin for(int i = 0; i < 10; i++) { if(panalogs[i] && panalogs[i]->pin == uspin) { analogRanges[0][i] = code_seen('L') ? code_value() : 0; analogRanges[1][i] = code_seen('H') ? code_value() : 0; break; } } } break; case 305: // M305 - toggle digital read during inactivity M305 P<pin> T<target> 0 or 1 for target value, default 0 // wont assign pin 0 as its sensitive // Looks for target value for pin during inactive, if so publish with <digitalpin> header and 1 - pin, 2 - value uspin = code_seen('P') ? code_value() : 0; digitarg = code_seen('T') ? code_value() : 0; // this is a permanent pin assignment so dont add if its already assigned if( assignPin(uspin) ) { for(int i = 0; i < 10; i++) { if(!pdigitals[i]) { pdigitals[i] = new Digital(uspin); pdigitals[i]->pinMode(INPUT); digitalTarget[i] = digitarg; break; } } } else { for(int i = 0; i < 10; i++) { if(pdigitals[i] && pdigitals[i]->pin == uspin) { digitalTarget[i] = digitarg; break; } } } break; case 306:// M306 - INPUT_PULLUP toggle digital read during inactivity M306 P<pin> T<target> 0 or 1 for target value, default 0 // Looks for target value for pin during inactive, if so publish with <digitalpin> header and 1 - pin 2 - value uspin = code_seen('P') ? code_value() : 0; digitarg = code_seen('T') ? code_value() : 0; // this is a permanent pin assignment so dont add if its already assigned if( assignPin(uspin) ) { for(int i = 0; i < 10; i++) { if(!pdigitals[i]) { pdigitals[i] = new Digital(uspin); pdigitals[i]->pinMode(INPUT_PULLUP); digitalTarget[i] = digitarg; break; } } } else { for(int i = 0; i < 10; i++) { if(pdigitals[i] && pdigitals[i]->pin == uspin) { digitalTarget[i] = digitarg; break; } } } break; case 349: // M349 /* if(code_seen('P')) bedKp = code_value(); if(code_seen('I')) bedKi = scalePID_i(code_value()); if(code_seen('D')) bedKd = scalePID_d(code_value()); updatePID(); SERIAL_PROTOCOL(MSG_OK); SERIAL_PROTOCOL(" p:"); SERIAL_PROTOCOL(bedKp); SERIAL_PROTOCOL(" i:"); SERIAL_PROTOCOL(unscalePID_i(bedKi)); SERIAL_PROTOCOL(" d:"); SERIAL_PROTOCOL(unscalePID_d(bedKd)); SERIAL_PROTOCOLLN(""); */ break; case 350: break; case 351: break; case 400: break; case 401: break; case 402: break; case 444: // M444 - set battery warning threshold V<volts*10>!!!!!!!!!!!!!!!!!! REMEMBER ITS TIMES 10 !!!!!!!!!!!!!!!!!! if(code_seen('V')) { BatteryThreshold = code_value(); // times 10!!! } break; case 445: // M445 - Turn off pulsed write pin - disable PWM P<pin> pin_number = -1; if (code_seen('P')) pin_number = code_value(); unassignPin(pin_number); for(int i = 0; i < 10; i++) { if(ppwms[i] && ppwms[i] == pin_number) { ppwms[i]->pwmWrite(0,0); // default is 2, clear on match. to turn off, use 0 delete ppwms[i]; ppwms[i] = 0; break; } } break; case 500: // M500 Store settings in EEPROM Config_StoreSettings(); break; case 501: // M501 Read settings from EEPROM Config_RetrieveSettings(); break; case 502: // M502 Revert to default settings Config_ResetDefault(); break; case 503: // M503 print settings currently in memory Config_PrintSettings(); break; case 540: //if(code_seen('S')) abort_on_endstop_hit = code_value() > 0; break; case 600: break; case 605: break; case 666: break; case 700: // return stats // Check startup - does nothing if bootloader sets MCUSR to 0 mcu = MCUSR; if(mcu & 1) SERIAL_PGMLN(MSG_POWERUP); if(mcu & 2) SERIAL_PGMLN(MSG_EXTERNAL_RESET); if(mcu & 4) SERIAL_PGMLN(MSG_BROWNOUT_RESET); if(mcu & 8) SERIAL_PGMLN(MSG_WATCHDOG_RESET); if(mcu & 32) SERIAL_PGMLN(MSG_SOFTWARE_RESET); MCUSR=0; SERIAL_PGM(VERSION_STRING); #ifdef STRING_VERSION_CONFIG_H #ifdef STRING_CONFIG_H_AUTHOR SERIAL_PGM(MSG_CONFIGURATION_VER); SERIAL_PGM(STRING_VERSION_CONFIG_H); SERIAL_PGM(MSG_AUTHOR); SERIAL_PGMLN(STRING_CONFIG_H_AUTHOR); SERIAL_PGM("Compiled: "); SERIAL_PGM(__DATE__); #endif #endif SERIAL_PGM(MSG_FREE_MEMORY); SERIAL_PORT.println(freeMemory()); SERIAL_PORT.flush(); break; case 701: // Report digital pins in use SERIAL_PGMLN("Digital Pins:"); for(int i = 0; i < 10; i++) { if( pdigitals[i] ) { SERIAL_PORT.print(pdigitals[i]->pin); switch(pdigitals[i]->mode) { case INPUT: SERIAL_PGMLN(" INPUT"); break; case INPUT_PULLUP: SERIAL_PGMLN(" INPUT_PULLUP"); break; case OUTPUT: SERIAL_PGMLN(" OUTPUT"); break; } } } SERIAL_PORT.println(); SERIAL_PORT.flush(); break; case 702: // Report analog pins in use SERIAL_PGMLN("Analog Pins:"); for(int i = 0; i < 10; i++) { if( panalogs[i] ) { SERIAL_PORT.print(panalogs[i]->pin); switch(panalogs[i]->mode) { case INPUT: SERIAL_PGMLN(" INPUT"); break; case INPUT_PULLUP: SERIAL_PGMLN(" INPUT_PULLUP"); break; case OUTPUT: SERIAL_PGMLN(" OUTPUT"); break; } } } SERIAL_PORT.println(); SERIAL_PORT.flush(); break; case 703: // Report ultrasonic pins in use SERIAL_PGMLN("Ultrasonic Pins:"); for(int i = 0; i < 10; i++) { if( psonics[i] ) { SERIAL_PGM("Pin:"); SERIAL_PORT.println(psonics[i]->getPin()); } } SERIAL_PORT.flush(); break; case 704: // Report PWM pins in use SERIAL_PGMLN("PWM Pins:"); for(int i = 0; i < 10; i++) { if( ppwms[i] ) { SERIAL_PGM("Pin:"); SERIAL_PORT.print(ppwms[i]->pin); SERIAL_PGM(" Timer channel:"); SERIAL_PORT.print(ppwms[i]->channel); switch(ppwms[i]->mode) { case INPUT: SERIAL_PGM(" INPUT"); break; case INPUT_PULLUP: SERIAL_PGM(" INPUT_PULLUP"); break; case OUTPUT: SERIAL_PGM(" OUTPUT"); break; } SERIAL_PORT.println(); } SERIAL_PORT.flush(); } break; case 705: // see if it has propulsion attributes declared with M3 as interrupt serviced switch(motor_status) { case 0: SERIAL_PGMLN("Multi Channel Motor Controller:"); break; case 1: SERIAL_PGMLN("H-Bridge Brushed DC Motor Driver(s):"); break; case 2: SERIAL_PGMLN("Brushless DC Motor Driver(s):"); break; } for(int i = 0 ; i < motorControl->getChannels(); i++) { //per channel SERIAL_PGM("Motor channel:"); SERIAL_PORT.print(i+1); SERIAL_PGM(" Min Power:"); SERIAL_PORT.print(motorControl->getMinMotorPower(i+1)); SERIAL_PGM(" Speed:"); SERIAL_PORT.print(motorControl->getMotorSpeed(i+1)); SERIAL_PGM(" Curr. Dir:"); SERIAL_PORT.print(motorControl->getCurrentDirection(i+1)); SERIAL_PGM(" Default. Dir:"); SERIAL_PORT.println(motorControl->getDefaultDirection(i+1)); SERIAL_PGM(" Encoder Pin:"); if(motorControl->getWheelEncoder(i+1)) { SERIAL_PORT.print(motorControl->getWheelEncoder(i+1)->pin); SERIAL_PGM(" Count:"); SERIAL_PORT.print(motorControl->getEncoderCount(i+1)); SERIAL_PGM(" Duration:"); SERIAL_PORT.println(motorControl->getMaxMotorDuration(i+1)); } else { SERIAL_PGMLN("None."); } } SERIAL_PGM("Ultrasonic pins:"); if( motorControl->totalUltrasonics() ) { SERIAL_PORT.println(motorControl->totalUltrasonics()); for(int j = 0; j < motorControl->totalUltrasonics(); j++) { SERIAL_PGM("Pin:"); SERIAL_PORT.print(psonics[motorControl->getUltrasonicIndex(i+1)]->getPin()); SERIAL_PGM(" Facing:"); SERIAL_PORT.print(motorControl->getUltrasonicFacing(i+1)); SERIAL_PGM(" Shutdown cm:"); SERIAL_PORT.println(motorControl->getMinMotorDist(i+1)); } } else { SERIAL_PGMLN("None."); } SERIAL_PORT.flush(); break; case 706: // Report all pins in use for(int i = 0; i < 100; i++) { if( pinAssignment(i) == PIN_ASSIGNED ) { SERIAL_PORT.print(i); SERIAL_PORT.print(','); } } SERIAL_PORT.println(); SERIAL_PORT.flush(); break; case 797: break; case 798: // Report controller status //SERIAL_PGMLN(motorCntrlHdr); if( motorControl->isConnected() ) { for(int i = 0; i < motorControl->getChannels() ; i++ ) { SERIAL_PGM("Motor Channel:"); SERIAL_PORT.println(i+1); char* buf = motorControl->getDriverInfo(i+1); while(*buf) { SERIAL_PORT.print(*buf); buf++; } } } SERIAL_PORT.println(); SERIAL_PORT.flush(); break; case 799: // Reset Motor controller motorControl->commandEmergencyStop(); break; case 800: break; case 801: // IMU prh = new PitchRollHeading(); orient = prh->getPitchRollHeading(); SERIAL_PGMLN(posCntrlHdr); SERIAL_PGM("1 "); SERIAL_PORT.println(orient.pitch); SERIAL_PGM("2 "); SERIAL_PORT.println(orient.roll); SERIAL_PGM("3 "); SERIAL_PORT.println(orient.heading); break; case 802: // Acquire analog pin data M802 Pnn Sxxx Mxxx P=Pin number, S=number readings, M=microseconds per reading. X - pullup. // Publish <dataset> 1 - pin, 2 - reading if( code_seen('P')) { apin = new Analog((uint8_t)code_value()); if( code_seen('X') ) apin->pinMode(INPUT_PULLUP); else apin->pinMode(INPUT); } nread = 0; if( code_seen('S') ) { nread = code_value(); } micros = 0; if( code_seen('M')) { micros = (uint32_t)code_value(); } values = new int(nread); for(int i = 0; i < nread; i++) { *(values+i) = apin->analogRead(); for(int j = 0; j < micros; j++) _delay_us(1); } SERIAL_PGMLN(datasetHdr); SERIAL_PORT.println(); for(int i = 0; i < nread; i++) { SERIAL_PORT.print(i+1); // sequence SERIAL_PORT.print(' '); // 0 element is pin number if( i == 0 ) SERIAL_PORT.println(apin->pin); else SERIAL_PORT.println(*(values+i)); // value } delete values; SERIAL_PORT.println(); SERIAL_PORT.flush(); break; case 803: break; case 907: break; case 908: // M908 Control digital trimpot directly. uint8_t current; if(code_seen('P')) channel=code_value(); if(code_seen('S')) current=code_value(); digitalPotWrite(channel, current); break; case 999: // M999: Reset Stopped = false; //lcd_reset_alert_level(); gcode_LastN = Stopped_gcode_LastN; //FlushSerialRequestResend(); if( watchdog_timer != NULL ) delete watchdog_timer; watchdog_timer = new WatchdogTimer(); watchdog_timer->watchdog_init(15); // 15 ms } // switch m code } else { // if M code SERIAL_PGMLN(MSG_UNKNOWN_COMMAND); //SERIAL_PORT.println(cmdbuffer[bufindr]); } }