Advertisement
Guest User

Lighty

a guest
Mar 18th, 2020
38,147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 19.46 KB | None | 0 0
  1. /*
  2.   DIY Lighty + SD + OLED + 5 way joystick + WS2812B RGB LED
  3.   Dirk Essl 2020
  4.   based on Digital Light Wand by Michael Ross
  5.  
  6.   Lighty is for use in specialized Light Painting Photography
  7.   Applications.
  8.  
  9.   The functionality that is included in this code is as follows:
  10.  
  11.   Menu System
  12.   1 - File select
  13.   2 - Brightness
  14.   3 - Initial Delay
  15.   4 - Frame Delay
  16.   5 - Repeat Times (The number of times to repeat the current file playback)
  17.   6 - Repeat Delay (if you want a delay between repeated files)
  18.  
  19.   This code supports direct reading of a 24bit Windows BMP from the SD card.
  20.   BMP images must be rotated 90 degrees clockwise and the width of the image should match the
  21.   number of pixels you have on your LED strip.  The bottom of the tool will be the INPUT
  22.   end of the strips where the Arduino is connected and will be the left side of the input
  23.   BMP image.
  24.  
  25.   Mick also added a Gamma Table from adafruit code which gives better conversion of 24 bit to
  26.   21 bit coloring.
  27.  
  28. */
  29.  
  30. // Library initialization
  31. #include            // Library for the WS2812 Neopixel Strip
  32. #include                           // Library for the SD Card
  33. #include
  34. #include
  35. #include
  36. #include
  37.  
  38. #define SCREEN_WIDTH 128 // OLED display width, in pixels
  39. #define SCREEN_HEIGHT 64 // OLED display height, in pixels
  40.  
  41. #define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
  42. Adafruit_SSD1306 lcd(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
  43.  
  44. // Pin assignments for the Arduino (Make changes to these if you use different Pins)
  45. #define SDssPin 53                        // SD card CS pin
  46. int NPPin = 6;                            // Data Pin for the NeoPixel LED Strip
  47. int AuxButton = 4;                       // Aux Select Button Pin
  48. int AuxButtonGND = 5;                    // Aux Select Button Ground Pin
  49. int g = 0;                                // Variable for the Green Value
  50. int b = 0;                                // Variable for the Blue Value
  51. int r = 0;                                // Variable for the Red Value
  52.  
  53. // Intial Variable declarations and assignments (Make changes to these if you want to change defaults)
  54. #define STRIP_LENGTH 144                  // Set the number of LEDs the LED Strip
  55. int frameDelay = 15;                      // default for the frame delay
  56. int menuItem = 1;                         // Variable for current main menu selection
  57. int initDelay = 0;                        // Variable for delay between button press and start of light sequence
  58. int repeat = 0;                           // Variable to select auto repeat (until select button is pressed again)
  59. int repeatDelay = 0;                      // Variable for delay between repeats
  60. int updateMode = 0;                       // Variable to keep track of update Modes
  61. int repeatTimes = 1;                      // Variable to keep track of number of repeats
  62. int brightness = 50;                      // Variable and default for the Brightness of the strip
  63.  
  64. // EEPROM setup. saves all values in eeprom. the mega has 4kb of eeprom storage
  65.  
  66. #include
  67. // the current address in the EEPROM (i.e. which byte we're going to write to next)
  68.  
  69. // set addresses for save
  70. int addrframeDelay = 0;                       // default for the frame delay
  71. int addrinitDelay = 20;                        // Variable for delay between button press and start of light sequence
  72. int addrrepeat = 30;                           // Variable to select auto repeat (until select button is pressed again)
  73. int addrrepeatDelay = 400;                      // Variable for delay between repeats
  74. int addrupdateMode = 50;                       // Variable to keep track of update Modes
  75. int addrrepeatTimes = 60;                      // Variable to keep track of number of repeats
  76. int addrbrightness = 70;                       // Variable and default for the Brightness of the strip
  77.  
  78. // Other program variable declarations, assignments, and initializations
  79. byte x;
  80.  
  81. // Declaring the two LED Strips and pin assignments to each
  82. Adafruit_NeoPixel strip = Adafruit_NeoPixel(STRIP_LENGTH, NPPin, NEO_GRB + NEO_KHZ800);
  83.  
  84. int key = -1;
  85. int oldkey = -1;
  86.  
  87. // SD Card Variables and assignments
  88. File root;
  89. File dataFile;
  90. String m_CurrentFilename = "";
  91. int m_FileIndex = 0;
  92. int m_NumberOfFiles = 0;
  93. String m_FileNames[200];
  94. long buffer[STRIP_LENGTH];
  95.  
  96. // Setup 5 way joystick
  97.  
  98. int uppin = 22;
  99. int downpin = 23;
  100. int leftpin = 24;
  101. int rightpin = 25;
  102. int entpin = 26;
  103.  
  104. // Setup loop to get everything ready.  This is only run once at power on or reset
  105. void setup() {
  106.  
  107.   pinMode(downpin, INPUT_PULLUP);
  108.   pinMode(leftpin, INPUT_PULLUP);
  109.   pinMode(rightpin, INPUT_PULLUP);
  110.   pinMode(entpin, INPUT_PULLUP);
  111.   pinMode(uppin, INPUT_PULLUP);
  112.  
  113.   // check if values in eeprom make sense, otherwise set default value
  114.   if (EEPROM.read(addrbrightness) >= 1 && EEPROM.read(addrbrightness) <= 100) {
  115.     brightness = EEPROM.read(addrbrightness);
  116.   } else {
  117.     brightness = 50;
  118.   }
  119.  
  120.   /*
  121.     if (EEPROM.read(addrrepeatTimes) >= 1 && EEPROM.read(addrrepeatTimes) <= 100) {
  122.       repeatTimes = EEPROM.read(addrrepeatTimes);
  123.     } else {
  124.       repeatTimes = 1;
  125.     }
  126.  
  127.     if (EEPROM.read(addrrepeatDelay) >= 0 && EEPROM.read(addrrepeatDelay) <= 10000) {
  128.       repeatDelay = EEPROM.read(addrrepeatDelay);
  129.     } else {
  130.       repeatDelay = 0;
  131.     }
  132.   */
  133.  
  134.   //Serial.begin(9600);
  135.  
  136.   // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  137.   if (!lcd.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
  138.     //Serial.println(F("SSD1306 allocation failed"));
  139.     for (;;); // Don't proceed, loop forever
  140.   }
  141.  
  142.   // Show initial display buffer contents on the screen --
  143.   // the library initializes this with an Adafruit splash screen.
  144.   lcd.display();
  145.   delay(100);
  146.  
  147.   // Clear the buffer
  148.   lcd.clearDisplay();
  149.   lcd.setTextSize(2);
  150.   lcd.setTextColor(SSD1306_WHITE);
  151.   lcd.setCursor(0, 0);
  152.   lcd.println(F("LIGHTY"));
  153.   lcd.setTextSize(1);
  154.   lcd.println(F("(c) Dirk Essl 2020"));
  155.   lcd.println(F("V0.9.20200314"));
  156.   lcd.println(F(" "));
  157.   lcd.println(F("..Initializing.."));
  158.   lcd.println("Please wait");
  159.   lcd.display();
  160.   delay(1000);
  161.  
  162.   pinMode(AuxButton, INPUT_PULLUP);
  163.   digitalWrite(AuxButton, INPUT_PULLUP);
  164.   pinMode(AuxButtonGND, INPUT_PULLUP);
  165.   digitalWrite(AuxButtonGND, INPUT_PULLUP);
  166.  
  167.   setupLEDs();
  168.   setupSDcard();
  169.   ClearStrip(0);
  170.  
  171. }
  172.  
  173. // The Main Loop for the program starts here...
  174. // This will loop endlessly looking for a key press to perform a function
  175. void loop() {
  176.   switch (menuItem) {
  177.     case 1:
  178.       lcd.clearDisplay();
  179.       lcd.setTextSize(2);
  180.       lcd.setTextColor(SSD1306_WHITE);
  181.       lcd.setCursor(0, 0);
  182.       lcd.println(F("LIGHTY"));
  183.       lcd.setTextSize(1);
  184.       lcd.println(F("1:File Select "));
  185.       lcd.println(m_CurrentFilename);
  186.       lcd.display();
  187.       break;
  188.     case 2:
  189.       lcd.clearDisplay();
  190.       lcd.setTextSize(2);
  191.       lcd.setTextColor(SSD1306_WHITE);
  192.       lcd.setCursor(0, 0);
  193.       lcd.println(F("LIGHTY"));
  194.       lcd.setTextSize(1);
  195.       lcd.println(F("2:Brightness "));
  196.       lcd.println(brightness);
  197.       lcd.display();
  198.       break;
  199.     case 3:
  200.       lcd.clearDisplay();
  201.       lcd.setTextSize(2);
  202.       lcd.setTextColor(SSD1306_WHITE);
  203.       lcd.setCursor(0, 0);
  204.       lcd.println(F("LIGHTY"));
  205.       lcd.setTextSize(1);
  206.       lcd.println(F("3:Init Delay "));
  207.       lcd.println(initDelay);
  208.       lcd.display();
  209.       break;
  210.     case 4:
  211.       lcd.clearDisplay();
  212.       lcd.setTextSize(2);
  213.       lcd.setTextColor(SSD1306_WHITE);
  214.       lcd.setCursor(0, 0);
  215.       lcd.println(F("LIGHTY"));
  216.       lcd.setTextSize(1);
  217.       lcd.println(F("4:Frame Delay"));
  218.       lcd.println(frameDelay);
  219.       lcd.display();
  220.       break;
  221.     case 5:
  222.       lcd.clearDisplay();
  223.       lcd.setTextSize(2);
  224.       lcd.setTextColor(SSD1306_WHITE);
  225.       lcd.setCursor(0, 0);
  226.       lcd.println(F("LIGHTY"));
  227.       lcd.setTextSize(1);
  228.       lcd.println(F("5:Repeat Times"));
  229.       lcd.println(repeatTimes);
  230.       lcd.display();
  231.       break;
  232.     case 6:
  233.       lcd.clearDisplay();
  234.       lcd.setTextSize(2);
  235.       lcd.setTextColor(SSD1306_WHITE);
  236.       lcd.setCursor(0, 0);
  237.       lcd.println(F("LIGHTY"));
  238.       lcd.setTextSize(1);
  239.       lcd.println(F("6:Repeat Delay"));
  240.       lcd.println(repeatDelay);
  241.       lcd.display();
  242.       break;
  243.   }
  244.  
  245.   int keypress = ReadKeypad();
  246.   delay(50);
  247.  
  248.   if ((keypress == 4) || (digitalRead(AuxButton) == LOW)) {   // The select key was pressed
  249.  
  250.     lcd.clearDisplay();
  251.     lcd.setTextSize(2);
  252.     lcd.setTextColor(SSD1306_WHITE);
  253.     lcd.setCursor(0, 0);
  254.     lcd.println(F(" "));
  255.     lcd.setTextSize(1);
  256.     lcd.println(F("Now Playing"));
  257.     lcd.println(m_CurrentFilename);
  258.     lcd.display();
  259.  
  260.     delay(initDelay);
  261.     if (repeatTimes > 1) {
  262.       for (int x = repeatTimes; x > 0; x--) {
  263.         SendFile(m_CurrentFilename);
  264.         delay(repeatDelay);
  265.       }
  266.     }
  267.     else {
  268.       SendFile(m_CurrentFilename);
  269.     }
  270.     ClearStrip(0);
  271.   }
  272.   if (keypress == 0) {                    // The Right Key was Pressed
  273.     switch (menuItem) {
  274.       case 1:                             // Select the Next File
  275.         //BackLightOn();
  276.         if (m_FileIndex < m_NumberOfFiles - 1) {
  277.           m_FileIndex++;
  278.         }
  279.         else {
  280.           m_FileIndex = 0;                // On the last file so wrap round to the first file
  281.         }
  282.         DisplayCurrentFilename();
  283.         break;
  284.       case 2:                             // Adjust Brightness
  285.         if (brightness < 100) {
  286.           brightness += 1;
  287.         }
  288.         break;
  289.       case 3:                             // Adjust Initial Delay + 1 second
  290.         initDelay += 1000;
  291.         break;
  292.       case 4:                             // Adjust Frame Delay + 1 milliseconds
  293.         frameDelay += 1;
  294.         break;
  295.       case 5:                             // Adjust Repeat Times + 1
  296.         repeatTimes += 1;
  297.         break;
  298.       case 6:                             // Adjust Repeat Delay + 100 milliseconds
  299.         repeatDelay += 100;
  300.         break;
  301.     }
  302.   }
  303.  
  304.   if (keypress == 3) {                    // The Left Key was Pressed
  305.     switch (menuItem) {                   // Select the Previous File
  306.       case 1:
  307.         //BackLightOn();
  308.         if (m_FileIndex > 0) {
  309.           m_FileIndex--;
  310.         }
  311.         else {
  312.           m_FileIndex = m_NumberOfFiles - 1;   // On the last file so wrap round to the first file
  313.         }
  314.         DisplayCurrentFilename();
  315.         delay(500);
  316.         break;
  317.       case 2:                             // Adjust Brightness
  318.         //BackLightOn();
  319.         if (brightness > 1) {
  320.           brightness -= 1;
  321.           EEPROM.put(addrbrightness, brightness);
  322.  
  323.         }
  324.         break;
  325.       case 3:                             // Adjust Initial Delay - 1 second
  326.         if (initDelay > 0) {
  327.           initDelay -= 1000;
  328.           EEPROM.put(addrinitDelay, initDelay);
  329.         }
  330.         break;
  331.       case 4:                             // Adjust Frame Delay - 1 millisecond
  332.         if (frameDelay > 0) {
  333.           frameDelay -= 1;
  334.           EEPROM.put(addrframeDelay, frameDelay);
  335.         }
  336.         break;
  337.       case 5:                             // Adjust Repeat Times - 1
  338.         if (repeatTimes > 1) {
  339.           repeatTimes -= 1;
  340.           EEPROM.put(addrrepeatTimes, repeatTimes);
  341.         }
  342.         break;
  343.       case 6:                             // Adjust Repeat Delay - 100 milliseconds
  344.         if (repeatDelay > 0) {
  345.           repeatDelay -= 100;
  346.           EEPROM.put(addrrepeatDelay, repeatDelay);
  347.         }
  348.         break;
  349.     }
  350.   }
  351.  
  352. //if (digitalRead(uppin) == LOW) key = 1;
  353.  
  354.   if (digitalRead(uppin) == LOW) {                 // The up key was pressed
  355.     delay(50);
  356.     if (menuItem == 1) {
  357.       menuItem = 6;
  358.     }
  359.     else {
  360.       menuItem -= 1;
  361.     }
  362.   }
  363.   if (( keypress == 2)) {                 // The down key was pressed
  364.     if (menuItem == 6) {
  365.       menuItem = 1;
  366.     }
  367.     else {
  368.       menuItem += 1;
  369.     }
  370.   }
  371.  
  372. }
  373.  
  374. void setupLEDs() {
  375.   strip.begin();
  376.   strip.show();
  377. }
  378.  
  379.  
  380. void setupSDcard() {
  381.   pinMode(SDssPin, OUTPUT);
  382.  
  383.   while (!SD.begin(SDssPin)) {
  384.     lcd.println("SD init failed! ");
  385.     lcd.display();
  386.     delay(2000);
  387.     lcd.clearDisplay();
  388.     delay(500);
  389.   }
  390.   //lcd.clearDisplay();
  391.   lcd.print("SD init done.   ");
  392.   delay(1000);
  393.   root = SD.open("/");
  394.   lcd.clearDisplay();
  395.   lcd.print("Scanning files  ");
  396.   delay(500);
  397.   GetFileNamesFromSD(root);
  398.   isort(m_FileNames, m_NumberOfFiles);
  399.   m_CurrentFilename = m_FileNames[0];
  400.   DisplayCurrentFilename();
  401. }
  402.  
  403. int ReadKeypad() {
  404.   {
  405.     if (digitalRead(uppin) == LOW) key = 1;
  406.     else key = -1;
  407.   }
  408.   {
  409.     if (digitalRead(downpin) == LOW) key = 2;
  410.     else key = -1;
  411.   }
  412.   {
  413.     if (digitalRead(leftpin) == LOW) key = 3;
  414.     //else key = oldkey;
  415.   }
  416.   {
  417.     if (digitalRead(rightpin) == LOW) key = 0;
  418.     //else key = oldkey;
  419.   }
  420.   {
  421.     if (digitalRead(entpin) == LOW) key = 4;
  422.     //else key = oldkey;
  423.   }
  424.  
  425.  
  426.   if (key != oldkey) {                    // if keypress is detected
  427.     delay(250);                            // wait for debounce time
  428.     key = key;
  429.     if (key != oldkey) {
  430.       oldkey = key;
  431.       if (key >= 0) {
  432.         return key;
  433.       }
  434.     }
  435.   }
  436.   return key;
  437. }
  438.  
  439. void SendFile(String Filename) {
  440.   char temp[14];
  441.   Filename.toCharArray(temp, 14);
  442.   dataFile = SD.open(temp);
  443.  
  444.   // if the file is available send it to the LED's
  445.   if (dataFile) {
  446.     ReadTheFile();
  447.     dataFile.close();
  448.   }
  449.   else {
  450.     lcd.clearDisplay();
  451.     lcd.print("  Error reading ");
  452.     lcd.setCursor(4, 1);
  453.     lcd.print("file");
  454.     delay(1000);
  455.     lcd.clearDisplay();
  456.     setupSDcard();
  457.     return;
  458.   }
  459. }
  460.  
  461. void DisplayCurrentFilename() {
  462.   m_CurrentFilename = m_FileNames[m_FileIndex];
  463.   lcd.setCursor(0, 1);
  464.   lcd.print("                ");
  465.   lcd.setCursor(0, 1);
  466.   lcd.print(m_CurrentFilename);
  467. }
  468.  
  469. void GetFileNamesFromSD(File dir) {
  470.   int fileCount = 0;
  471.   String CurrentFilename = "";
  472.   while (1) {
  473.     File entry =  dir.openNextFile();
  474.     if (! entry) {
  475.       // no more files
  476.       m_NumberOfFiles = fileCount;
  477.       entry.close();
  478.       break;
  479.     }
  480.     else {
  481.       if (entry.isDirectory()) {
  482.         //GetNextFileName(root);
  483.       }
  484.       else {
  485.         CurrentFilename = entry.name();
  486.         if (CurrentFilename.endsWith(".bmp") || CurrentFilename.endsWith(".BMP") ) { //find files with our extension only
  487.           m_FileNames[fileCount] = entry.name();
  488.           fileCount++;
  489.         }
  490.       }
  491.     }
  492.     entry.close();
  493.   }
  494. }
  495.  
  496. void latchanddelay(int dur) {
  497.   strip.show();
  498.   delay(dur);
  499. }
  500.  
  501. void ClearStrip(int duration) {
  502.   int x;
  503.   for (x = 0; x < STRIP_LENGTH; x++) {
  504.     strip.setPixelColor(x, 0);
  505.   }
  506.   strip.show();
  507. }
  508.  
  509. uint32_t readLong() {
  510.   uint32_t retValue;
  511.   byte incomingbyte;
  512.  
  513.   incomingbyte = readByte();
  514.   retValue = (uint32_t)((byte)incomingbyte);
  515.  
  516.   incomingbyte = readByte();
  517.   retValue += (uint32_t)((byte)incomingbyte) << 8;
  518.  
  519.   incomingbyte = readByte();
  520.   retValue += (uint32_t)((byte)incomingbyte) << 16;
  521.  
  522.   incomingbyte = readByte();
  523.   retValue += (uint32_t)((byte)incomingbyte) << 24;
  524.  
  525.   return retValue;
  526. }
  527.  
  528. uint16_t readInt() {
  529.   byte incomingbyte;
  530.   uint16_t retValue;
  531.  
  532.   incomingbyte = readByte();
  533.   retValue += (uint16_t)((byte)incomingbyte);
  534.  
  535.   incomingbyte = readByte();
  536.   retValue += (uint16_t)((byte)incomingbyte) << 8;
  537.  
  538.   return retValue;
  539. }
  540.  
  541. int readByte() {
  542.   int retbyte = -1;
  543.   while (retbyte < 0) retbyte = dataFile.read();
  544.   return retbyte;
  545. }
  546.  
  547. void getRGBwithGamma() {
  548.   g = gamma(readByte()) / (101 - brightness);
  549.   b = gamma(readByte()) / (101 - brightness);
  550.   r = gamma(readByte()) / (101 - brightness);
  551. }
  552.  
  553. void ReadTheFile() {
  554. #define MYBMP_BF_TYPE           0x4D42
  555. #define MYBMP_BF_OFF_BITS       54
  556. #define MYBMP_BI_SIZE           40
  557. #define MYBMP_BI_RGB            0L
  558. #define MYBMP_BI_RLE8           1L
  559. #define MYBMP_BI_RLE4           2L
  560. #define MYBMP_BI_BITFIELDS      3L
  561.  
  562.   uint16_t bmpType = readInt();
  563.   uint32_t bmpSize = readLong();
  564.   uint16_t bmpReserved1 = readInt();
  565.   uint16_t bmpReserved2 = readInt();
  566.   uint32_t bmpOffBits = readLong();
  567.   bmpOffBits = 54;
  568.  
  569.   /* Check file header */
  570.   if (bmpType != MYBMP_BF_TYPE || bmpOffBits != MYBMP_BF_OFF_BITS) {
  571.     lcd.setCursor(0, 0);
  572.     lcd.print("not a bitmap");
  573.     delay(1000);
  574.     return;
  575.   }
  576.  
  577.   /* Read info header */
  578.   uint32_t imgSize = readLong();
  579.   uint32_t imgWidth = readLong();
  580.   uint32_t imgHeight = readLong();
  581.   uint16_t imgPlanes = readInt();
  582.   uint16_t imgBitCount = readInt();
  583.   uint32_t imgCompression = readLong();
  584.   uint32_t imgSizeImage = readLong();
  585.   uint32_t imgXPelsPerMeter = readLong();
  586.   uint32_t imgYPelsPerMeter = readLong();
  587.   uint32_t imgClrUsed = readLong();
  588.   uint32_t imgClrImportant = readLong();
  589.  
  590.   /* Check info header */
  591.   if ( imgSize != MYBMP_BI_SIZE || imgWidth <= 0 ||
  592.        imgHeight <= 0 || imgPlanes != 1 ||
  593.        imgBitCount != 24 || imgCompression != MYBMP_BI_RGB ||
  594.        imgSizeImage == 0 )
  595.   {
  596.     lcd.setCursor(0, 0);
  597.     lcd.print("Unsupported");
  598.     lcd.setCursor(0, 1);
  599.     lcd.print("Bitmap Use 24bpp");
  600.     delay(1000);
  601.     return;
  602.   }
  603.  
  604.   int displayWidth = imgWidth;
  605.   if (imgWidth > STRIP_LENGTH) {
  606.     displayWidth = STRIP_LENGTH;           //only display the number of led's we have
  607.   }
  608.  
  609.  
  610.   /* compute the line length */
  611.   uint32_t lineLength = imgWidth * 3;
  612.   if ((lineLength % 4) != 0)
  613.     lineLength = (lineLength / 4 + 1) * 4;
  614.  
  615.  
  616.  
  617.   // Note:
  618.   // The x,r,b,g sequence below might need to be changed if your strip is displaying
  619.   // incorrect colors.  Some strips use an x,r,b,g sequence and some use x,r,g,b
  620.   // Change the order if needed to make the colors correct.
  621.  
  622.   for (int y = imgHeight; y > 0; y--) {
  623.     int bufpos = 0;
  624.     for (int x = 0; x < displayWidth; x++) {
  625.       uint32_t offset = (MYBMP_BF_OFF_BITS + (((y - 1) * lineLength) + (x * 3))) ;
  626.       dataFile.seek(offset);
  627.  
  628.       getRGBwithGamma();
  629.  
  630.       strip.setPixelColor(x, r, b, g);
  631.  
  632.     }
  633.     latchanddelay(frameDelay);
  634.   }
  635. }
  636.  
  637.  
  638.  
  639. // Sort the filenames in alphabetical order
  640. void isort(String * filenames, int n) {
  641.   for (int i = 1; i < n; ++i) {
  642.     String j = filenames[i];
  643.     int k;
  644.     for (k = i - 1; (k >= 0) && (j < filenames[k]); k--) {
  645.       filenames[k + 1] = filenames[k];
  646.     }
  647.     filenames[k + 1] = j;
  648.   }
  649. }
  650.  
  651. PROGMEM const unsigned char gammaTable[]  = {
  652.   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  653.   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,
  654.   1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,
  655.   2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,
  656.   4,  4,  4,  4,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  7,  7,
  657.   7,  7,  7,  8,  8,  8,  8,  9,  9,  9,  9, 10, 10, 10, 10, 11,
  658.   11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16,
  659.   16, 17, 17, 17, 18, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22,
  660.   23, 23, 24, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30,
  661.   30, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 37, 37, 38, 38, 39,
  662.   40, 40, 41, 41, 42, 43, 43, 44, 45, 45, 46, 47, 47, 48, 49, 50,
  663.   50, 51, 52, 52, 53, 54, 55, 55, 56, 57, 58, 58, 59, 60, 61, 62,
  664.   62, 63, 64, 65, 66, 67, 67, 68, 69, 70, 71, 72, 73, 74, 74, 75,
  665.   76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
  666.   92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 104, 105, 106, 107, 108,
  667.   109, 110, 111, 113, 114, 115, 116, 117, 118, 120, 121, 122, 123, 125, 126, 127
  668. };
  669.  
  670. inline byte gamma(byte x) {
  671.   return pgm_read_byte(&gammaTable[x]);
  672. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement