Étape 9: Firmware
Le firmware contrôle les feux de bord de RVB. Le code a été écrit dans l’IDE Arduino. Aller à http://arduino.cc/ pour télécharger l’IDE Arduino.
Avant de pouvoir compiler et flash le code, vous devrez également suivre le guide pour le bijou. Il nécessite quelques ajouts à l’IDE avant que votre ordinateur peut communiquer avec le bijou. Pour le guide, rendez-vous ici : https://learn.adafruit.com/introducing-trinket/introduction
Avec toutes ces choses, vous pouvez ouvrir le code. Télécharger ou copier/coller le code ci-dessous pour commencer. Il y a quelques choses que vous pouvez modifier pour personnaliser vos propres feux de bord :
« OffTime » est à la fois que le capteur doit être éteinte avant que la roue se met en veille.
« AnimationSpeed » est le temps entre chaque mise à jour de l’animation de ralenti. 83MS est la valeur par défaut, qui est une révolution complète de l’animation chaque seconde (1000ms/12modules = 83.33ms)
« AnimationSlots » est la quantité de couleurs différentes, il y a sur une jante. Dans mon cas, il y a 5. 2 x large (au début et fin), 1 x blanc, jaune 1 x et 1 x rouge. Sachez que chaque fente animation consomme de la mémoire RAM et le bijou n’a pas beaucoup de cela.
- n = l’emplacement des encoches animation (0-4). C’est la quantité de couleurs différentes, que vous pouvez avoir sur un seul bord. Vous commencez à 0 (où le capteur et l’aimant alignement) et se termine à 255 (quelques mm avant l’alignement). Aucun couleur n’est également une fente.
- m = la chose en cours de définition. m = 0 est le point de départ de la couleur donnée, m = 1 est le point de terminaison (doit être plus élevé). m = 2 est si la couleur bleue doit être sur (1 = Oui, 0 = non). m = 3 est si la couleur rouge doit être sur (1 = Oui, 0 = non). m = 4 est si la couleur verte doit être sur (1 = Oui, 0 = non).
/*<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 }