The full process of calibration in WriteInstinct.ino is:
1. You don't know where the servos are pointing at before calibration. So you don't attach the legs.
2. Upload skills, which include one "calib" posture, it's a posture with all joints at zero position. There's also a "rest" posture. Of course, you won't see the postures because you haven't attached the legs. But you can imagine that the servos will rotate when switching between the two postures.
These postures are also shown in 6.4.3 of the instruction document.
You have to enter 'Y' to save skills to EEPROM. Right after that, the program will read the rest posture and rotate all servos to rest position, then shut them down to avoid vibration. Still don't attach the legs.
3. The program will ask you whether to calibrate MPU. You can enter 'n' to skip if you have already done so. You can now understand why I put Nybble to rest state before calibrating MPU. It's much easier to lay Nybble level on the table.
4. Now if you enter 'c', the program will read the calib posture and execute. All the servos are supposed to rotate like crazy (but they are actually transforming from rest position) until they stop at calibrate position. Then you can attach the legs one joint by one joint, perpendicular to nearby references on frames. It's easier to attach knee joints before shoulder joints.
Even if you attach legs in the direction of calibrate posture before entering 'c', the servos are actually in rest posture. Once you enter 'c', the legs are going to move, but would probably hit something in the middle. In that case, the motor will be forced to stop and becomes a pure resistor. It will pull a large current, generate heat and cause a voltage drop on the chip. That will further disturb the signals, causing more abnormal behaviors.
5. After attaching all the joints, Nybble will stand on its knees as in the calibrate state. The directions of legs won't be perfect. Don't force the legs to move, but enter the "c Joint Angle" commands to adjust the angles. Use the included L-shape tuner as a reference for fine-tuning each joint. You can enter 's' after calibrating each servo in case of any interruption in the process.
6. The calibration values are saved to ATmega328P's onboard EEPROM. They won't change unless some voltage shock happens to cause a "bit flip" when the processor is accessing the memory location. But it's very rare. Next time you want to calibrate, you don't need to take off the legs. You can also calibrate within OpenCat.ino.
The debug code
In file included from sketch/OpenCat.h:85:0,
from /Nybble/OpenCat/WriteInstinct/WriteInstinct.ino:31:
/Applications/Arduino/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/Wire/src/Wire.h: In member function 'void Motion::loadDataFromI2cEeprom(unsigned int&)':
/Applications/Arduino/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/Wire/src/Wire.h:68:13: note: candidate 1: uint8_t TwoWire::requestFrom(int, int)
uint8_t requestFrom(int, int);
^~~~~~~~~~~
/Applications/Arduino/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/Wire/src/Wire.h:65:13: note: candidate 2: uint8_t TwoWire::requestFrom(uint8_t, uint8_t)
uint8_t requestFrom(uint8_t, uint8_t);
^~~~~~~~~~~
I am not expert but message after compile seems to indicate that the wire.h is not working properly?
I copied the debug code from test buzzer to the writeinstinct code and can only get 1st a few characters to print on the serial monitor for the WriteInstinct program using a test point below I inserted into the code. The 2nd test point never prints?
void setup()
{ Serial.begin(115200);
Serial.println("1st test point");
#ifdef PIXEL_PIN
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pixels.clear(); // Set all pixel colors to 'off'
// pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255
pixels.setPixelColor(NUMPIXELS - 1, pixels.Color(LIT_ON, 0, 0));
pixels.show(); // Send the updated pixel colors to the hardware.
#endif
// join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
Serial.println("2nd testpoint");
Serial.begin(BAUD_RATE);
Serial.setTimeout(5);
delay(1);
while (!Serial);//check here