Paso 9: Firmware
El firmware controla las luces de borde RGB. El código fue escrito en el IDE de Arduino. Ir a http://arduino.cc/ para descargar el IDE de Arduino.
Antes de poder compilar y flash el código, usted también necesitará seguir a la guía para el Abalorio. Requiere algunas adiciones al IDE antes de que su computadora puede comunicarse con el Abalorio. Para el guía, ir aquí: https://learn.adafruit.com/introducing-trinket/introduction
Con todas estas cosas, puede abrir el código. Descargar o copiar/pegar el código siguiente para empezar. Hay algunas cosas que usted puede modificar para personalizar sus propias luces de borde:
'OffTime' es el momento que el sensor debe estar apagado antes de la rueda entra en inactividad.
'AnimationSpeed' es el tiempo entre cada actualización de la animación de ralentí. 83ms es el predeterminado, que es una revolución de la animación cada segundo (1000ms/12modules = 83.33ms)
'AnimationSlots' es la cantidad de diferentes colores en un borde. En mi caso hay 5. 2 x fuera (al inicio y al final), blanco 1 x, 1 x amarillo y rojo 1 x. Ser conscientes de que cada ranura animación consume memoria RAM y el Abalorio no tiene mucho de esto.
- n = la ranura de las ranuras de animación (0-4). Esta es la cantidad de colores diferentes que puede tener un borde. Desde 0 (donde el sensor y el imán alinean) y termina en 255 (unos milímetros antes de la alineación). Ningún color es también una ranura.
- m = lo que se está definiendo. m = 0 es el punto de partida del color dado, m = 1 es el punto final (tiene que ser mayor). m = 2 es si el color azul tiene que ser en (1 = sí, 0 = no). m = 3 es si debe ser en el color rojo (1 = sí, 0 = no). m = 4 es si debe ser en el color verde (1 = sí, 0 = no).
/*<br> RGB rim light firmware V1.00 The firmware used to control the RGB bicycle rim lights. Uses a TLE4905L Hall effect sensor (or other unipolar hall effect sensor) to measure the rpm of a bicycle wheel and lights up specific groups of RGB leds to always light up the front white (front wheel) and the back red (back wheel) and have special animations if wanted by the user. The RGB modules are daisy chained 74HC595 IC's that each drive 2 sets of RGB leds. It is configurable for any amount of modules and animations. This code is written in the hope that it will be useful, but no garuantees. Written by Y. de Haas, latest version written 24-12-2014 (dd-mm-yyyy (like it should be)) More information on <a href="http://Ytec3D.com" rel="nofollow"> http://Ytec3D.com </a> */ //pin layout const byte LatchPin = 1; const byte VoltagePin = 2; const byte ClockPin = 3; const byte DataPin = 4; const byte HallSensor = 0; //configurations const byte NumOfModules = 6; //The amount of 74HC595 modules daisy chained together const byte BrightnessStates = 8; //The amount of brighness steps. More is more accurate, but lower frequency const long OffTime = 2500000; //The amount of time (us) the hall sensor can sense nothing before the wheel registers as not moving const byte PWMStepTime = 250; //The amount of microseconds each PWM step takes const byte AnimationSpeed = 83; //in milliseconds (default = 83) const byte CatchUpSpeed = 20; //the amount of millis before the animation catches up to wheel location by 1/255th of a rotation const word LowVoltageThreshold = 725; //voltage at which first warning start const word LowVoltageBlink[2] = {200, 5000}; //on and off intervals for low voltage const word CritVoltageThreshold = 695; //voltage at which critical warning starts const word CritVoltageBlink[2] = {200, 1000}; //on and off intervals for low voltage //Animation information const byte AnimationSlots = 5; //the amount of colors in the animation (OFF is also a color) //NumOfAnimations: what animation, AnimationSlots: The amount of defined colors in one animation, byte LedAnimation[AnimationSlots][5]; //5: (0)start coordinate, (1)end coordinate, (2) blue on, (3) red on, (4)green on //variables word WheelLocation = 0; byte AnimationLocation = 0; int AnimationLocationOffset = 0, AnimationCurrentOffset = 0; byte WheelMoving = 0; //states if the wheel is moving or not, needed for startup byte PWMState = 0; byte AnimationState = 12; byte HallHistory = 1; byte WheelMovementHistory = 0; byte VoltageBlinkState = 0; unsigned long WheelHistory = 0, WheelSpinTime = 0; unsigned long PWMTarget = 0; unsigned long AnimationTarget = 0; unsigned long CorrectionTarget = 0; unsigned long VoltageBlinkTarget = 0; //LedState[n] states which color each led on each module is in 'BrightnessStates' intervals. LedState 0 is off, Ledstate 'BrightnessStates' is full brightness. byte LedState[NumOfModules*2][3]; //LedState[n][0]=blue, LedState[n][1]=red and LedState[n][2]=green boolean PWMLedState[NumOfModules*2][3]; //if leds should be on in relation to PWM byte TempOutputRegister[NumOfModules]; void setup() { pinMode(LatchPin, OUTPUT); pinMode(ClockPin, OUTPUT); pinMode(DataPin, OUTPUT); pinMode(VoltagePin, INPUT); pinMode(HallSensor, INPUT); //warning, inverted, 0 is sensing, 1 is not sensing. SetAnimations(); } void loop() { if (WheelMoving == 0 || WheelMoving == 2) //if the wheel is not moving or in state 2, do the animation { StationaryAnimation(); WheelMovementHistory = 0; } //if the hall sensor senses, update wheel states if (digitalRead(HallSensor) == 0 && HallHistory == 1) { HallHistory = 0; if (WheelMoving == 0) //if wheel was not moving, go to first revolution { WheelMoving = 2; WheelHistory = micros(); } else if (WheelMoving == 1) //if wheel is in stable motion { WheelSpinTime = micros() - WheelHistory; WheelHistory = micros(); //determine offset based on current location AnimationLocationOffset = AnimationLocationOffset + 255 - WheelLocation; if (AnimationLocationOffset < -127) { AnimationLocationOffset += 255; } else if (AnimationLocationOffset > 127) { AnimationLocationOffset -= 255; } WheelLocation = 0; } else if (WheelMoving == 2) //if wheel has moved one revolution { WheelMoving = 1; WheelSpinTime = micros() - WheelHistory; WheelHistory = micros(); WheelLocation = 0; AnimationLocation = 0; } } //calculate wheel position based on wheel spin time and history if (WheelMoving == 1) { //remap position to 0-255 float WheelTemp = micros() - WheelHistory; WheelTemp = WheelTemp * 255; WheelTemp = WheelTemp / WheelSpinTime; WheelLocation = int(WheelTemp); //check is wheel was moving, if not, match wheel location to animation location if (WheelMovementHistory == 0) { WheelMovementHistory = 1; AnimationLocation = WheelLocation; } AnimationLocation = WheelLocation; //temporary link wheel location to animation location //update led animation states based on animation location long TempAnimationLocation; for (byte i=0; i < NumOfModules*2; i++) //for the amount of leds { TempAnimationLocation = 256 * i; TempAnimationLocation = TempAnimationLocation / (NumOfModules*2); TempAnimationLocation = AnimationLocation + TempAnimationLocation; TempAnimationLocation = TempAnimationLocation % 256; //TempAnimationLocation = i*21; //recalculate the location based on what module is on for (byte j=0; j < AnimationSlots; j++) //for the amount of color on the animations { if (TempAnimationLocation >= LedAnimation[j][0] && TempAnimationLocation < LedAnimation[j][1]) { LedState[i][0] = LedAnimation[j][2]; LedState[i][1] = LedAnimation[j][3]; LedState[i][2] = LedAnimation[j][4]; } } } } //Reset Hall history to 1 if the sensor no longer senses. if (digitalRead(HallSensor) == 1 && HallHistory == 0) { HallHistory = 1; } //overrule led states for half of the leds if voltage is low or critical if (analogRead(1) < LowVoltageThreshold) { word TempVoltage = analogRead(1); if (millis() > VoltageBlinkTarget) { //set new target if (TempVoltage > CritVoltageThreshold && TempVoltage < LowVoltageThreshold) { VoltageBlinkTarget = millis() + LowVoltageBlink[VoltageBlinkState]; } else if (TempVoltage < CritVoltageThreshold) { VoltageBlinkTarget = millis() + CritVoltageBlink[VoltageBlinkState]; } //set new blink state if (VoltageBlinkState == 1) { VoltageBlinkState = 0; } else { VoltageBlinkState = 1; } } if (VoltageBlinkState == 1) { for (byte i=0; i < NumOfModules*2; i++) { LedState[i][0] = 0; LedState[i][1] = 1; LedState[i][2] = 0; } } } UpdateLeds(); //Go to WheelMoving = 0 if the wheel is stationary for too long if (WheelMoving == 1 || WheelMoving == 2) { if (micros() > WheelHistory + OffTime) { WheelMoving = 0; } } } //Functions ---------------------------------------------------------------------------------------------------------------------- void UpdateLeds() { bitWrite(TempOutputRegister[0], 2, LedState[1][0]); bitWrite(TempOutputRegister[0], 3, LedState[1][1]); bitWrite(TempOutputRegister[0], 4, LedState[1][2]); bitWrite(TempOutputRegister[0], 5, LedState[0][0]); bitWrite(TempOutputRegister[0], 6, LedState[0][1]); bitWrite(TempOutputRegister[0], 7, LedState[0][2]); bitWrite(TempOutputRegister[1], 2, LedState[3][0]); bitWrite(TempOutputRegister[1], 3, LedState[3][1]); bitWrite(TempOutputRegister[1], 4, LedState[3][2]); bitWrite(TempOutputRegister[1], 5, LedState[2][0]); bitWrite(TempOutputRegister[1], 6, LedState[2][1]); bitWrite(TempOutputRegister[1], 7, LedState[2][2]); bitWrite(TempOutputRegister[2], 2, LedState[5][0]); bitWrite(TempOutputRegister[2], 3, LedState[5][1]); bitWrite(TempOutputRegister[2], 4, LedState[5][2]); bitWrite(TempOutputRegister[2], 5, LedState[4][0]); bitWrite(TempOutputRegister[2], 6, LedState[4][1]); bitWrite(TempOutputRegister[2], 7, LedState[4][2]); bitWrite(TempOutputRegister[3], 2, LedState[7][0]); bitWrite(TempOutputRegister[3], 3, LedState[7][1]); bitWrite(TempOutputRegister[3], 4, LedState[7][2]); bitWrite(TempOutputRegister[3], 5, LedState[6][0]); bitWrite(TempOutputRegister[3], 6, LedState[6][1]); bitWrite(TempOutputRegister[3], 7, LedState[6][2]); bitWrite(TempOutputRegister[4], 2, LedState[9][0]); bitWrite(TempOutputRegister[4], 3, LedState[9][1]); bitWrite(TempOutputRegister[4], 4, LedState[9][2]); bitWrite(TempOutputRegister[4], 5, LedState[8][0]); bitWrite(TempOutputRegister[4], 6, LedState[8][1]); bitWrite(TempOutputRegister[4], 7, LedState[8][2]); bitWrite(TempOutputRegister[5], 2, LedState[11][0]); bitWrite(TempOutputRegister[5], 3, LedState[11][1]); bitWrite(TempOutputRegister[5], 4, LedState[11][2]); bitWrite(TempOutputRegister[5], 5, LedState[10][0]); bitWrite(TempOutputRegister[5], 6, LedState[10][1]); bitWrite(TempOutputRegister[5], 7, LedState[10][2]); //set all led states to registers digitalWrite(LatchPin, LOW); shiftOut(DataPin, ClockPin, MSBFIRST, TempOutputRegister[0]); shiftOut(DataPin, ClockPin, MSBFIRST, TempOutputRegister[1]); shiftOut(DataPin, ClockPin, MSBFIRST, TempOutputRegister[2]); shiftOut(DataPin, ClockPin, MSBFIRST, TempOutputRegister[3]); shiftOut(DataPin, ClockPin, MSBFIRST, TempOutputRegister[4]); shiftOut(DataPin, ClockPin, MSBFIRST, TempOutputRegister[5]); digitalWrite(LatchPin, HIGH); } void StationaryAnimation() { if (millis() > AnimationTarget) { //set next target and update state AnimationTarget = millis() + AnimationSpeed; AnimationState ++; if (AnimationState > 11) { AnimationState = 0; } //animation for (int i = 0; i<12; i++) { byte temp = i; temp += AnimationState; if (temp > 11) { temp -= 12; } if (temp >= 0 && temp < 1) { LedState[i][0] = 0; LedState[i][1] = 1; LedState[i][2] = 0; } else if (temp >= 2 && temp < 4) { LedState[i][0] = 0; LedState[i][1] = 1; LedState[i][2] = 1; } else if (temp >= 4 && temp < 6) { LedState[i][0] = 0; LedState[i][1] = 0; LedState[i][2] = 1; } else if (temp >= 6 && temp < 8) { LedState[i][0] = 1; LedState[i][1] = 0; LedState[i][2] = 1; } else if (temp >= 8 && temp < 10) { LedState[i][0] = 1; LedState[i][1] = 0; LedState[i][2] = 0; } else if (temp >= 10 && temp < 12) { LedState[i][0] = 1; LedState[i][1] = 1; LedState[i][2] = 0; } } } }<br> void SetAnimations() { //uncomment the animation you want to show and comment the other animation //rear wheel animation /* LedAnimation[0][0] = 60; //start point LedAnimation[0][1] = 100; //end point LedAnimation[0][2] = 1; //blue led LedAnimation[0][3] = 1; //red led LedAnimation[0][4] = 1; //green led LedAnimation[1][0] = 100; //start point LedAnimation[1][1] = 140; //end point LedAnimation[1][2] = 0; //blue led LedAnimation[1][3] = 1; //red led LedAnimation[1][4] = 1; //green led LedAnimation[2][0] = 140; //start point LedAnimation[2][1] = 200; //end point LedAnimation[2][2] = 0; //blue led LedAnimation[2][3] = 1; //red led LedAnimation[2][4] = 0; //green led LedAnimation[3][0] = 200; //start point LedAnimation[3][1] = 255; //end point LedAnimation[3][2] = 0; //blue led LedAnimation[3][3] = 0; //red led LedAnimation[3][4] = 0; //green led LedAnimation[4][0] = 0; //start point LedAnimation[4][1] = 60; //end point LedAnimation[4][2] = 0; //blue led LedAnimation[4][3] = 0; //red led LedAnimation[4][4] = 0; //green led */ //front wheel animation LedAnimation[0][0] = 40; //start point LedAnimation[0][1] = 120; //end point LedAnimation[0][2] = 1; //blue led LedAnimation[0][3] = 1; //red led LedAnimation[0][4] = 1; //green led LedAnimation[1][0] = 120; //start point LedAnimation[1][1] = 150; //end point LedAnimation[1][2] = 0; //blue led LedAnimation[1][3] = 1; //red led LedAnimation[1][4] = 1; //green led LedAnimation[2][0] = 150; //start point LedAnimation[2][1] = 190; //end point LedAnimation[2][2] = 0; //blue led LedAnimation[2][3] = 1; //red led LedAnimation[2][4] = 0; //green led LedAnimation[3][0] = 190; //start point LedAnimation[3][1] = 255; //end point LedAnimation[3][2] = 0; //blue led LedAnimation[3][3] = 0; //red led LedAnimation[3][4] = 0; //green led LedAnimation[4][0] = 0; //start point LedAnimation[4][1] = 40; //end point LedAnimation[4][2] = 0; //blue led LedAnimation[4][3] = 0; //red led LedAnimation[4][4] = 0; //green led }