Advertisement
Guest User

Arduino Digital Light Wand 1.02

a guest
Dec 1st, 2011
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.35 KB | None | 0 0
  1. //
  2. // Arduino Digital Light Wand + SD + LCD V1.02
  3. // Fixed the SD init problem (removing card, trying to send a file (which fails) now re-inits the card.
  4. // Backlight now fades out, instead of just switching off.
  5. //
  6.  
  7.  
  8.  
  9. #include <SD.h>
  10. #include <LEDStrip.h>
  11. #include <LiquidCrystal.h>
  12.  
  13. #define SIPIN 30
  14. #define DIPIN 31
  15. #define CLKPIN 32
  16. #define LATCHPIN 33
  17. LEDStrip mystrip(DIPIN,SIPIN,LATCHPIN,CLKPIN);
  18. #define SPULSES 5000
  19. #define STRIP_LENGTH 48
  20. #define BACKLIGHT 10
  21. byte BL = B10000000; // Black / Off
  22. #define SDssPin 53  //SD card CS pin
  23. int frameDelay = 10; // default for the frame delay
  24. LiquidCrystal lcd(8, 9, 4, 5, 6, 7);  //Init the LCD
  25.  
  26. //BacklightControl to save battery Life
  27. boolean BackLightTimer = false;
  28. int BackLightTimeout = 2000;
  29. int BackLightTemp =  BackLightTimeout;
  30.  
  31. //Stuff for the Keypad
  32. int adc_key_val[5] ={
  33.   30, 150, 360, 535, 760 };
  34. int NUM_KEYS = 5;
  35. int adc_key_in;
  36. int key=-1;
  37. int oldkey=-1;
  38.  
  39. File root;
  40. File dataFile;
  41. String m_CurrentFilename = "";
  42. int m_FileIndex = 0;
  43. int m_NumberOfFiles = 0;
  44. String m_FileNames[200]; //yep this is bad, but unless you are going to have over 200 images on your lightwand..
  45.  
  46. long buffer[STRIP_LENGTH];
  47. char tmpbuffer[20];
  48. long lCntr[1];
  49.  
  50. struct bitmapblock {
  51.   byte len;
  52.   byte r;
  53.   byte g;
  54.   byte b;
  55. }
  56. mybitmapblock;
  57.  
  58. char buf[4];
  59. int fileVersion;
  60. uint32_t bitmapOffset;
  61. int bitmapHeight;
  62. uint32_t bitmapWidth;
  63. int StartDelay;
  64. int EndDelay;
  65. int StrobeOn;
  66. int StrobeOff;
  67. byte VReversed;
  68. byte HReversed;
  69.  
  70. //Colour weights for the HL1606..
  71. uint8_t HL1606highred = 100;
  72. uint8_t HL1606highgreen = 100;
  73. uint8_t HL1606highblue = 100;
  74. uint8_t HL1606lowred = 20;
  75. uint8_t HL1606lowgreen = 20;
  76. uint8_t HL1606lowblue = 20;
  77.  
  78.  
  79.  
  80. void setup()
  81. {
  82.   Serial.begin(9600);
  83.   setupLEDs();
  84.   setupLCDdisplay();
  85.   setupSDcard();
  86.   BackLightOn();
  87. }
  88.  
  89. void setupLEDs()
  90. {
  91.   ClearStrip(100);
  92. }
  93.  
  94. void setupLCDdisplay()
  95. {
  96.   lcd.begin(16, 2);
  97.   lcd.print("  *** DLW ***");
  98.   lcd.setCursor(0, 1);
  99.   lcd.print("Initializing...");
  100.   delay(1000);  
  101.   lcd.clear();
  102.   //pinMode(BACKLIGHT, OUTPUT);
  103.   //digitalWrite(BACKLIGHT,LOW);
  104.  
  105. }
  106.  
  107. void setupSDcard()
  108. {
  109.   pinMode(SDssPin, OUTPUT);
  110.  
  111.   while (!SD.begin(SDssPin)) {
  112.     BackLightOn();
  113.     lcd.print("SD init failed!");
  114.     delay(1000);
  115.     lcd.clear();
  116.     delay(500);
  117.   }
  118.   lcd.clear();
  119.   lcd.print("SD init done.");
  120.   delay(1000);
  121.   root = SD.open("/");
  122.   lcd.clear();
  123.   lcd.print("Scanning files");
  124.   delay(500);
  125.   GetFileNamesFromSD(root);
  126.   isort(m_FileNames, m_NumberOfFiles);
  127.   m_CurrentFilename = m_FileNames[0];
  128.   DisplayCurrentFilename();
  129.  
  130. }
  131.  
  132. void latchanddelay(int dur)
  133. {
  134.   mystrip.latch();
  135.   delay(dur);
  136. }
  137.  
  138. void ClearStrip(int duration)
  139. {
  140.   int x;
  141.   for(x=0;x<STRIP_LENGTH;x++)
  142.   {
  143.     mystrip.pushCmd(BL);
  144.   }
  145.   latchanddelay(duration);
  146. }
  147.  
  148. void MultiPush(int Cmd, int Cnt) {
  149.   while(Cnt-->0) mystrip.pushCmd(Cmd);
  150. }
  151.  
  152. int ReadKeypad()
  153. {
  154.   adc_key_in = analogRead(0);    // read the value from the sensor  
  155.   digitalWrite(13, HIGH);  
  156.   key = get_key(adc_key_in);                // convert into key press
  157.  
  158.   if (key != oldkey)                    // if keypress is detected
  159.   {
  160.     delay(50);      // wait for debounce time
  161.     adc_key_in = analogRead(0);    // read the value from the sensor  
  162.     key = get_key(adc_key_in);              // convert into key press
  163.     if (key != oldkey)             
  164.     {          
  165.       oldkey = key;
  166.       if (key >=0){
  167.         return key;
  168.       }
  169.     }
  170.   }
  171.   return key;
  172. }
  173.  
  174.  
  175. // Convert ADC value to key number
  176. int get_key(unsigned int input)
  177. {
  178.   int k;
  179.   for (k = 0; k < NUM_KEYS; k++)
  180.   {
  181.     if (input < adc_key_val[k])
  182.     {        
  183.       return k;
  184.     }
  185.   }
  186.   if (k >= NUM_KEYS)
  187.     k = -1;     // No valid key pressed
  188.   return k;
  189. }
  190.  
  191.  
  192. //The Main menu starts here...
  193. void loop()
  194. {
  195.   int keypress = ReadKeypad();
  196.   if ( keypress == 1) //up key (step up through the filenames)
  197.   {
  198.     BackLightOn();
  199.     if (m_FileIndex > 0)
  200.     {
  201.       m_FileIndex--;
  202.     }
  203.     else
  204.     {
  205.       m_FileIndex = m_NumberOfFiles -1; //wrap round to the last file
  206.     }
  207.  
  208.     DisplayCurrentFilename();
  209.     delay(500);
  210.   }
  211.  
  212.   if ( keypress == 2) //down key (step down through the filenames)
  213.   {
  214.     BackLightOn();
  215.     if (m_FileIndex < m_NumberOfFiles -1)
  216.     {
  217.       m_FileIndex++;
  218.     }
  219.     else
  220.     {
  221.       m_FileIndex = 0;//wrap round to the 1st file again
  222.     }
  223.     DisplayCurrentFilename();
  224.     delay(500);
  225.   }
  226.  
  227.   if (keypress == 4)//select key (send out the selected file)
  228.   {
  229.     SendFile(m_CurrentFilename);
  230.   }
  231.  
  232.   if(keypress == 0) //right key (frame delay +)
  233.   {
  234.     BackLightOn();
  235.     if (frameDelay < 200)
  236.     {
  237.       frameDelay+=5;
  238.     }
  239.     ShowFrameDelay();
  240.   }
  241.  
  242.   if(keypress == 3)//left key (frame delay -)
  243.   {
  244.     BackLightOn();
  245.     if (frameDelay > 5)
  246.     {
  247.       frameDelay-=5;
  248.     }
  249.     ShowFrameDelay();
  250.   }
  251.  
  252.   if (BackLightTimer == true) BackLightTime();
  253.  
  254. }
  255.  
  256. void BackLightOn()
  257. {
  258.   analogWrite(BACKLIGHT,255);
  259.   BackLightTimer = true;
  260.   int BackLightTemp =  BackLightTimeout;
  261. }
  262.  
  263. void BackLightTime()
  264. {
  265.   if ((BackLightTemp <= 255) && (BackLightTemp >= 0))
  266.   {
  267.     analogWrite(BACKLIGHT,BackLightTemp);
  268.     delay(1);
  269.   }
  270.  
  271.   if (BackLightTemp <= 0)
  272.   {
  273.     BackLightTimer = false;
  274.     BackLightTemp =  BackLightTimeout;
  275.     analogWrite(BACKLIGHT,0);
  276.   }
  277.   else
  278.   {
  279.     BackLightTemp --;
  280.     delay(1);
  281.   }
  282. }
  283.  
  284. void ShowFrameDelay()
  285. {
  286.   lcd.clear();
  287.   lcd.print("Frame delay:");
  288.   lcd.setCursor(0,1);
  289.   lcd.print(frameDelay);
  290.   delay(500);
  291.   DisplayCurrentFilename();
  292. }
  293.  
  294.  
  295. void SendFile(String Filename)
  296. {
  297.   lcd.clear();
  298.   lcd.print("Sending File");
  299.   lcd.setCursor(0, 1);
  300.   lcd.print(Filename);
  301.   char temp[14];
  302.   Filename.toCharArray(temp,14);
  303.  
  304.   dataFile = SD.open(temp);
  305.  
  306.   // if the file is available send it to the LED's
  307.   if (dataFile)
  308.   {
  309.     ReadTheFile();
  310.     dataFile.close();
  311.     ClearStrip(100);
  312.   }  
  313.   else
  314.   {
  315.     lcd.clear();
  316.     lcd.print("  Error reading");
  317.     lcd.setCursor(4, 1);
  318.     lcd.print("file");
  319.     BackLightOn();
  320.     delay(1000);
  321.     lcd.clear();
  322.     setupSDcard();//try to re-init the SD card...(this was failing, but a fix can be done below)
  323.                   //In the SD.CPP in the BEGIN class which starts
  324.                   // boolean SDClass::begin(uint8_t csPin) {
  325.                   //
  326.                   //it needs the line below to be added
  327.                   //
  328.                   // if (root.isOpen()) root.close();   // allows repeated calls
  329.                   //
  330.                   // Just before the line
  331.                   // return card.init(SPI_HALF_SPEED, csPin) &&
  332.                   //
  333.                   //
  334.                  
  335.                  
  336.     return;
  337.   }
  338.   DisplayCurrentFilename();
  339. }
  340.  
  341. void DisplayCurrentFilename()
  342. {
  343.   m_CurrentFilename = m_FileNames[m_FileIndex];
  344.   lcd.clear();
  345.   lcd.print(m_CurrentFilename);
  346. }
  347.  
  348. void GetFileNamesFromSD(File dir)
  349. {
  350.   int fileCount = 0;
  351.   String CurrentFilename = "";
  352.   while(1)
  353.   {
  354.     File entry =  dir.openNextFile();
  355.     if (! entry) {
  356.       // no more files
  357.       m_NumberOfFiles = fileCount;
  358.       break;
  359.     }
  360.     else
  361.     {
  362.       if (entry.isDirectory()) {
  363.         //GetNextFileName(root);
  364.       }
  365.       else {
  366.         CurrentFilename = entry.name();
  367.         if (CurrentFilename.endsWith(".LSB"))//find files with our extension only
  368.         {
  369.           m_FileNames[fileCount] = entry.name();
  370.           fileCount++;
  371.         }
  372.       }
  373.     }
  374.   }
  375. }
  376.  
  377. uint32_t readLong()
  378. {
  379.   uint32_t retValue;
  380.   int incomingbyte;
  381.  
  382.   incomingbyte=readByte();
  383.   retValue=(uint32_t)((byte)incomingbyte)<<24;
  384.  
  385.   incomingbyte=readByte();
  386.   retValue+=(uint32_t)((byte)incomingbyte)<<16;
  387.  
  388.   incomingbyte=readByte();
  389.   retValue+=(uint32_t)((byte)incomingbyte)<<8;
  390.  
  391.   incomingbyte=readByte();
  392.   retValue+=(uint32_t)((byte)incomingbyte);
  393.  
  394.   return retValue;
  395. }
  396.  
  397. int readInt()
  398. {
  399.   int incomingbyte;
  400.   uint16_t retValue;
  401.  
  402.   incomingbyte=readByte();
  403.   retValue+=(int)((byte)incomingbyte)<<8;
  404.  
  405.   incomingbyte=readByte();
  406.   retValue+=(int)((byte)incomingbyte);
  407.  
  408.   return retValue;
  409. }
  410.  
  411. int readByte()
  412. {
  413.   int retbyte=-1;
  414.   while(retbyte<0) retbyte= dataFile.read();
  415.   return retbyte;
  416. }
  417.  
  418. void writeRGB(uint8_t Red,uint8_t Green,uint8_t Blue)
  419. {
  420.   byte colorByte = 128;
  421.   //
  422.   //My strip seemed to have B + G swapped so I altered it here!
  423.   //
  424.   if (Blue > HL1606highblue) colorByte |= 16; //Bright Blue
  425.   else if (Blue > HL1606lowblue) colorByte |= 32; //Dim Blue
  426.   if (Red > HL1606highred) colorByte |= 4; //Bright Red
  427.   else if (Red > HL1606lowred) colorByte |= 8; //Dim Red
  428.   if (Green > HL1606highgreen) colorByte |= 1; //Bright Green
  429.   else if (Green > HL1606lowgreen) colorByte |= 2; //Dim Green
  430.   mystrip.pushCmd(colorByte);
  431. }
  432.  
  433.  
  434. void post_frame (void) {
  435.   for(int LED_number = 0 ; LED_number < STRIP_LENGTH ; LED_number++)
  436.   {
  437.     long this_led_color = buffer[LED_number]; //24 bits of color data
  438.     int r=(((this_led_color>>16) & 0xff)>>1);
  439.     int g=(((this_led_color>>8) & 0xff)>>1);
  440.     int b=(((this_led_color) & 0xff)>>1);
  441.     writeRGB(r,g,b);
  442.   }
  443.   latchanddelay(frameDelay);
  444. }
  445.  
  446. void ReadTheFile()
  447. {
  448.   long WAND=readLong();
  449.   fileVersion=readByte();
  450.   bitmapOffset = readLong();
  451.   bitmapHeight = readInt();
  452.   bitmapWidth = readLong();
  453.   StartDelay = readByte();
  454.   EndDelay = readByte();
  455.   StrobeOn = readInt();
  456.   StrobeOff = readInt();
  457.   VReversed = readByte();
  458.   HReversed = readByte();
  459.  
  460.   Serial.println("file version ");
  461.   Serial.println(fileVersion,DEC);
  462.   Serial.println("bitmap offset");
  463.   Serial.println(bitmapOffset,DEC);
  464.   Serial.println("bitmap height");
  465.   Serial.println(bitmapHeight,DEC);
  466.   Serial.println("bitmap Width");
  467.   Serial.println(bitmapWidth,DEC);
  468.   Serial.println("start delay");
  469.   Serial.println(StartDelay,DEC);
  470.   Serial.println("end delay");
  471.   Serial.println(EndDelay,DEC);
  472.   Serial.println("strobe off");
  473.   Serial.println(StrobeOff,DEC);
  474.   Serial.println("strobe on");
  475.   Serial.println(StrobeOn,DEC);
  476.   Serial.println("vReversed");
  477.   Serial.println(VReversed,DEC);
  478.   Serial.println("hReversed");
  479.   Serial.println(HReversed,DEC);
  480.  
  481.   if(readLong()!=0L) Serial.println("Invalid file");
  482.   else Serial.println("Read in the header successfully");
  483.  
  484.   //ClearStrip(100);
  485.   long filepos=0;
  486.  
  487.   for(int x=0;x<bitmapWidth;x++) {
  488.     int bufpos=0;
  489.     //Serial.println("Serial buffer is at ");
  490.     //Serial.println(Serial1.available(),DEC);
  491.     //  Serial.println("At column" + x );
  492.     while(bufpos<bitmapHeight) {
  493.       mybitmapblock.len=readByte();
  494.       mybitmapblock.r=readByte();
  495.       mybitmapblock.g=readByte();
  496.       mybitmapblock.b=readByte();
  497.  
  498.       filepos=filepos+4;
  499.       for(int j=0;j<mybitmapblock.len;j++) {
  500.         buffer[bufpos]=(long)mybitmapblock.r << 16;
  501.         buffer[bufpos]|=(long)mybitmapblock.g << 8;
  502.         buffer[bufpos++]|=(long)mybitmapblock.b;
  503.       }
  504.       if(bufpos>bitmapHeight)
  505.       {
  506.         Serial.println("FATAL ERROR - Problem with length of bitmap");
  507.         while(1) delay(1);
  508.       }
  509.     }
  510.     post_frame();
  511.   }
  512.   Serial.println("Finished");
  513.   ClearStrip(100);
  514. }
  515.  
  516. //sort the filenames in alphabetical order
  517. void isort(String *filenames, int n)
  518. {
  519.   for (int i = 1; i < n; ++i)
  520.   {
  521.     String j = filenames[i];
  522.     int k;
  523.     for (k = i - 1; (k >= 0) && (j < filenames[k]); k--)
  524.     {
  525.       filenames[k + 1] = filenames[k];
  526.     }
  527.     filenames[k + 1] = j;
  528.   }
  529. }
  530.  
  531.  
  532.  
  533.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement