Stap 9: Firmware
De firmware bepaalt de RGB velg lichten. De code is geschreven in de Arduino IDE. Ga naar http://arduino.cc/ voor het downloaden van de Arduino IDE.
Voordat u kunt compileren en flash de code, moet je ook om de gids voor de trinket te volgen. Het vereist aantal toevoegingen aan de IDE voordat uw computer met de Trinket communiceren kan. Voor naar de vleugelman, ga hier: https://learn.adafruit.com/introducing-trinket/introduction
Met al deze dingen gedaan, zou u de code kunt openen. Het downloaden of kopieer en plak de code hieronder om te beginnen. Er zijn een paar dingen die je kunt tweaken om het aanpassen van uw eigen velg lichten:
'OffTime' is de tijd dat de sensor worden moet uitgeschakeld voordat het wiel inactief terechtkomt.
'AnimationSpeed' is de tijd tussen elke update van de niet-actieve animatie. 83ms is de standaard, die een revolutie van de animatie per seconde is (1000ms/12modules = 83.33ms)
'AnimationSlots' is de hoeveelheid verschillende kleuren er op een velg zijn. In mijn geval is er 5. 2 x af (aan het begin en einde), 1 x wit, 1 x geel en 1 x rood. Wees ervan bewust dat elke animatie sleuf geheugen van de RAM verbruikt en de trinket niet veel van dit hoeft.
- n = de sleuf van de animatie "slots" (0-4). Dit is de hoeveelheid verschillende kleuren die kunt u op een rand hebben. U beginnen bij 0 (waar de sensor en de magneet uitlijnen) en eindigt bij 255 (een paar mm vóór de uitlijning). Geen kleur is ook een slot.
- m = het ding wordt gedefinieerd. m = 0 is het beginpunt van de opgegeven kleur, m = 1 is het eindpunt (dient te worden hoger). m = 2 is als de blauwe kleur worden moet op (1 = Ja, 0 = nee). m = 3 is als de rode kleur worden moet op (1 = Ja, 0 = nee). m = 4 is als de groene kleur worden moet op (1 = Ja, 0 = nee).
/*<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 }