Merge remote-tracking branch 'adafruit/master'
This commit is contained in:
commit
6e75facefd
5 changed files with 99 additions and 13 deletions
|
|
@ -59,6 +59,7 @@ int iPupilFactor = 42;
|
||||||
uint32_t boopSum = 0;
|
uint32_t boopSum = 0;
|
||||||
bool booped = false;
|
bool booped = false;
|
||||||
int fixate = 7;
|
int fixate = 7;
|
||||||
|
uint8_t lightSensorFailCount = 0;
|
||||||
|
|
||||||
// For autonomous iris scaling
|
// For autonomous iris scaling
|
||||||
#define IRIS_LEVELS 7
|
#define IRIS_LEVELS 7
|
||||||
|
|
@ -191,19 +192,21 @@ void setup() {
|
||||||
eye[e].iris.startAngle = (e & 1) ? 512 : 0; // Rotate alternate eyes 180 degrees
|
eye[e].iris.startAngle = (e & 1) ? 512 : 0; // Rotate alternate eyes 180 degrees
|
||||||
eye[e].iris.angle = eye[e].iris.startAngle;
|
eye[e].iris.angle = eye[e].iris.startAngle;
|
||||||
eye[e].iris.mirror = 0;
|
eye[e].iris.mirror = 0;
|
||||||
eye[e].iris.spin = 0;
|
eye[e].iris.spin = 0.0;
|
||||||
|
eye[e].iris.iSpin = 0;
|
||||||
eye[e].sclera.color = 0xFFFF;
|
eye[e].sclera.color = 0xFFFF;
|
||||||
eye[e].sclera.data = NULL;
|
eye[e].sclera.data = NULL;
|
||||||
eye[e].sclera.filename = NULL;
|
eye[e].sclera.filename = NULL;
|
||||||
eye[e].sclera.startAngle = (e & 1) ? 512 : 0; // Rotate alternate eyes 180 degrees
|
eye[e].sclera.startAngle = (e & 1) ? 512 : 0; // Rotate alternate eyes 180 degrees
|
||||||
eye[e].sclera.angle = eye[e].sclera.startAngle;
|
eye[e].sclera.angle = eye[e].sclera.startAngle;
|
||||||
eye[e].sclera.mirror = 0;
|
eye[e].sclera.mirror = 0;
|
||||||
eye[e].sclera.spin = 0;
|
eye[e].sclera.spin = 0.0;
|
||||||
|
eye[e].sclera.iSpin = 0;
|
||||||
|
|
||||||
// Uncanny eyes carryover stuff for now, all messy:
|
// Uncanny eyes carryover stuff for now, all messy:
|
||||||
eye[e].blink.state = NOBLINK;
|
eye[e].blink.state = NOBLINK;
|
||||||
eye[e].eyeX = 512;
|
// eye[e].eyeX = 512;
|
||||||
eye[e].eyeY = 512;
|
// eye[e].eyeY = 512;
|
||||||
eye[e].blinkFactor = 0.0;
|
eye[e].blinkFactor = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -328,6 +331,12 @@ void setup() {
|
||||||
Serial.printf("Free RAM: %d\n", availableRAM());
|
Serial.printf("Free RAM: %d\n", availableRAM());
|
||||||
|
|
||||||
randomSeed(SysTick->VAL + analogRead(A2));
|
randomSeed(SysTick->VAL + analogRead(A2));
|
||||||
|
eyeOldX = eyeNewX = eyeOldY = eyeNewY = mapRadius; // Start in center
|
||||||
|
for(e=0; e<NUM_EYES; e++) { // For each eye...
|
||||||
|
eye[e].eyeX = eyeOldX;
|
||||||
|
eye[e].eyeY = eyeOldY;
|
||||||
|
}
|
||||||
|
lastLightReadTime = micros() + 2000000; // Delay initial light reading
|
||||||
}
|
}
|
||||||
|
|
||||||
// LOOP FUNCTION - CALLED REPEATEDLY UNTIL POWER-OFF -----------------------
|
// LOOP FUNCTION - CALLED REPEATEDLY UNTIL POWER-OFF -----------------------
|
||||||
|
|
@ -429,12 +438,21 @@ void loop() {
|
||||||
// both eyes. This comment has nothing to do with the code.
|
// both eyes. This comment has nothing to do with the code.
|
||||||
uint16_t rawReading = (lightSensorPin >= 100) ?
|
uint16_t rawReading = (lightSensorPin >= 100) ?
|
||||||
seesaw.analogRead(lightSensorPin - 100) : analogRead(lightSensorPin);
|
seesaw.analogRead(lightSensorPin - 100) : analogRead(lightSensorPin);
|
||||||
if(rawReading < lightSensorMin) rawReading = lightSensorMin; // Clamp light sensor range
|
if(rawReading <= 1023) {
|
||||||
else if(rawReading > lightSensorMax) rawReading = lightSensorMax; // to within usable range
|
if(rawReading < lightSensorMin) rawReading = lightSensorMin; // Clamp light sensor range
|
||||||
float v = (float)(rawReading - lightSensorMin) / (float)(lightSensorMax - lightSensorMin); // 0.0 to 1.0
|
else if(rawReading > lightSensorMax) rawReading = lightSensorMax; // to within usable range
|
||||||
v = pow(v, lightSensorCurve);
|
float v = (float)(rawReading - lightSensorMin) / (float)(lightSensorMax - lightSensorMin); // 0.0 to 1.0
|
||||||
lastLightValue = irisMin + v * irisRange;
|
v = pow(v, lightSensorCurve);
|
||||||
lastLightReadTime = t;
|
lastLightValue = irisMin + v * irisRange;
|
||||||
|
lastLightReadTime = t;
|
||||||
|
lightSensorFailCount = 0;
|
||||||
|
} else { // I2C error
|
||||||
|
if(++lightSensorFailCount >= 50) { // If repeated errors in succession...
|
||||||
|
lightSensorPin = -1; // Stop trying to use the light sensor
|
||||||
|
} else {
|
||||||
|
lastLightReadTime = t - LIGHT_INTERVAL + 40000; // Try again in 40 ms
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
irisValue = (irisValue * 0.97) + (lastLightValue * 0.03); // Filter response for smooth reaction
|
irisValue = (irisValue * 0.97) + (lastLightValue * 0.03); // Filter response for smooth reaction
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -556,8 +574,18 @@ void loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
float mins = (float)millis() / 60000.0;
|
float mins = (float)millis() / 60000.0;
|
||||||
eye[eyeNum].iris.angle = (int)((float)eye[eyeNum].iris.startAngle + eye[eyeNum].iris.spin * mins + 0.5);
|
if(eye[eyeNum].iris.iSpin) {
|
||||||
eye[eyeNum].sclera.angle = (int)((float)eye[eyeNum].sclera.startAngle + eye[eyeNum].sclera.spin * mins + 0.5);
|
// Spin works in fixed amount per frame (eyes may lose sync, but "wagon wheel" tricks work)
|
||||||
|
eye[eyeNum].iris.angle += eye[eyeNum].iris.iSpin;
|
||||||
|
} else {
|
||||||
|
// Keep consistent timing in spin animation (eyes stay in sync, no "wagon wheel" effects)
|
||||||
|
eye[eyeNum].iris.angle = (int)((float)eye[eyeNum].iris.startAngle + eye[eyeNum].iris.spin * mins + 0.5);
|
||||||
|
}
|
||||||
|
if(eye[eyeNum].sclera.iSpin) {
|
||||||
|
eye[eyeNum].sclera.angle += eye[eyeNum].sclera.iSpin;
|
||||||
|
} else {
|
||||||
|
eye[eyeNum].sclera.angle = (int)((float)eye[eyeNum].sclera.startAngle + eye[eyeNum].sclera.spin * mins + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
// END ONCE-PER-FRAME EYE ANIMATION ----------------------------------
|
// END ONCE-PER-FRAME EYE ANIMATION ----------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,9 @@ void loadConfig(char *filename) {
|
||||||
irisMirror = 0,
|
irisMirror = 0,
|
||||||
scleraMirror = 0,
|
scleraMirror = 0,
|
||||||
irisAngle = 0,
|
irisAngle = 0,
|
||||||
scleraAngle = 0;
|
scleraAngle = 0,
|
||||||
|
irisiSpin = 0,
|
||||||
|
scleraiSpin = 0;
|
||||||
float irisSpin = 0.0,
|
float irisSpin = 0.0,
|
||||||
scleraSpin = 0.0;
|
scleraSpin = 0.0;
|
||||||
JsonVariant iristv = doc["irisTexture"],
|
JsonVariant iristv = doc["irisTexture"],
|
||||||
|
|
@ -268,6 +270,10 @@ void loadConfig(char *filename) {
|
||||||
if(v.is<float>()) irisSpin = v.as<float>() * -1024.0;
|
if(v.is<float>()) irisSpin = v.as<float>() * -1024.0;
|
||||||
v = doc["scleraSpin"];
|
v = doc["scleraSpin"];
|
||||||
if(v.is<float>()) scleraSpin = v.as<float>() * -1024.0;
|
if(v.is<float>()) scleraSpin = v.as<float>() * -1024.0;
|
||||||
|
v = doc["irisiSpin"];
|
||||||
|
if(v.is<int>()) irisiSpin = v.as<int>();
|
||||||
|
v = doc["scleraiSpin"];
|
||||||
|
if(v.is<int>()) scleraiSpin = v.as<int>();
|
||||||
v = doc["irisMirror"];
|
v = doc["irisMirror"];
|
||||||
if(v.is<bool>() || v.is<int>()) irisMirror = v ? 1023 : 0;
|
if(v.is<bool>() || v.is<int>()) irisMirror = v ? 1023 : 0;
|
||||||
v = doc["scleraMirror"];
|
v = doc["scleraMirror"];
|
||||||
|
|
@ -294,6 +300,8 @@ void loadConfig(char *filename) {
|
||||||
eye[e].sclera.mirror = scleraMirror;
|
eye[e].sclera.mirror = scleraMirror;
|
||||||
eye[e].iris.spin = irisSpin;
|
eye[e].iris.spin = irisSpin;
|
||||||
eye[e].sclera.spin = scleraSpin;
|
eye[e].sclera.spin = scleraSpin;
|
||||||
|
eye[e].iris.iSpin = irisiSpin;
|
||||||
|
eye[e].sclera.iSpin = scleraiSpin;
|
||||||
// iris and sclera filenames are strdup'd for each eye rather than
|
// iris and sclera filenames are strdup'd for each eye rather than
|
||||||
// sharing a common pointer, reason being that it gets really messy
|
// sharing a common pointer, reason being that it gets really messy
|
||||||
// below when overriding one or the other and trying to do the right
|
// below when overriding one or the other and trying to do the right
|
||||||
|
|
@ -325,6 +333,10 @@ void loadConfig(char *filename) {
|
||||||
if(v.is<float>()) eye[e].iris.spin = v.as<float>() * -1024.0;
|
if(v.is<float>()) eye[e].iris.spin = v.as<float>() * -1024.0;
|
||||||
v = doc[eye[e].name]["scleraSpin"];
|
v = doc[eye[e].name]["scleraSpin"];
|
||||||
if(v.is<float>()) eye[e].sclera.spin = v.as<float>() * -1024.0;
|
if(v.is<float>()) eye[e].sclera.spin = v.as<float>() * -1024.0;
|
||||||
|
v = doc[eye[e].name]["irisiSpin"];
|
||||||
|
if(v.is<int>()) eye[e].iris.iSpin = v.as<int>();
|
||||||
|
v = doc[eye[e].name]["scleraiSpin"];
|
||||||
|
if(v.is<int>()) eye[e].sclera.iSpin = v.as<int>();
|
||||||
v = doc[eye[e].name]["irisMirror"];
|
v = doc[eye[e].name]["irisMirror"];
|
||||||
if(v.is<bool>() || v.is<int>()) eye[e].iris.mirror = v ? 1023 : 0;
|
if(v.is<bool>() || v.is<int>()) eye[e].iris.mirror = v ? 1023 : 0;
|
||||||
v = doc[eye[e].name]["scleraMirror"];
|
v = doc[eye[e].name]["scleraMirror"];
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,7 @@ typedef struct {
|
||||||
uint16_t startAngle; // INITIAL rotation 0-1023 CCW
|
uint16_t startAngle; // INITIAL rotation 0-1023 CCW
|
||||||
uint16_t angle; // CURRENT rotation 0-1023 CCW
|
uint16_t angle; // CURRENT rotation 0-1023 CCW
|
||||||
uint16_t mirror; // 0 = normal, 1023 = flip X axis
|
uint16_t mirror; // 0 = normal, 1023 = flip X axis
|
||||||
|
uint16_t iSpin; // Per-frame fixed integer spin, overrides 'spin' value
|
||||||
} texture;
|
} texture;
|
||||||
|
|
||||||
// Each eye then uses the following structure. Each eye must be on its own
|
// Each eye then uses the following structure. Each eye must be on its own
|
||||||
|
|
|
||||||
0
Pylint_and_CircuitPython/.circuitpython.skip
Normal file
0
Pylint_and_CircuitPython/.circuitpython.skip
Normal file
45
Pylint_and_CircuitPython/pylint_example.py
Normal file
45
Pylint_and_CircuitPython/pylint_example.py
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
import board
|
||||||
|
import digitalio
|
||||||
|
import adafruit_lis3dh
|
||||||
|
import touchio
|
||||||
|
import time
|
||||||
|
import neopixel
|
||||||
|
import adafruit_thermistor
|
||||||
|
|
||||||
|
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=0.2)
|
||||||
|
|
||||||
|
i2c = board.I2C()
|
||||||
|
int1 = digitalio.DigitalInOut(board.ACCELEROMETER_UNTERRUPT)
|
||||||
|
lis3dh = adafruit_lis3dh.LIS3DH_I2C(i2c, int1=int1)
|
||||||
|
|
||||||
|
circuit_playground_temperature = adafruit_thermistor.Thermistor(board.TEMPERATURE, 10000, 10000, 25, 3950)
|
||||||
|
|
||||||
|
touch_A1 = touchio.TouchIn(board.A1)
|
||||||
|
touch_A2 = touchio.TouchIn(board.A2)
|
||||||
|
|
||||||
|
led = digitalio.DigitalInOut(board.D13)
|
||||||
|
led.direction = digitalio.Direction.OUTPUT
|
||||||
|
|
||||||
|
button_A = digitalio.DigitalInOut(board.BUTTON_A)
|
||||||
|
button_A.direction = digitalio.Direction.INPUT
|
||||||
|
button_A.pull = digitalio.Pull.DOWN
|
||||||
|
|
||||||
|
while True:
|
||||||
|
x, y, z = lis3dh.acceleration
|
||||||
|
|
||||||
|
if button_A.value:
|
||||||
|
led.value = True
|
||||||
|
else:
|
||||||
|
led.value = False
|
||||||
|
|
||||||
|
print("Temperature:", circuit_playground_temperature.temperature)
|
||||||
|
print("Acceleration:", x, y, z)
|
||||||
|
|
||||||
|
if touch_A1.value:
|
||||||
|
pixels.fill((255, 0, 0))
|
||||||
|
if touch_A2.value:
|
||||||
|
pixels.fill((0, 0, 255))
|
||||||
|
else:
|
||||||
|
pixels.fill((0, 0, 0))
|
||||||
|
|
||||||
|
time.sleep(0.01)
|
||||||
Loading…
Reference in a new issue