SHOW:
|
|
- or go back to the newest paste.
1 | // 240824 | |
2 | - | // Arduino Digital Light Wand + SD + LCD V1.02 |
2 | + | |
3 | - | // Fixed the SD init problem (removing card, trying to send a file (which fails) now re-inits the card. |
3 | + | //LEDType = LPD8806 |
4 | - | // Backlight now fades out, instead of just switching off. |
4 | + | //HardwareSPI = True |
5 | //LCDDisplay = True | |
6 | //DualStrip =True | |
7 | //StripControl1 = 22 | |
8 | //StripControl2 = 23 | |
9 | - | #include <SD.h> |
9 | + | //bitmapWidth = 600 |
10 | - | #include <LEDStrip.h> |
10 | + | //WandLEDs = 32 |
11 | //delayOffset = 0 | |
12 | //numOffset = 0 | |
13 | - | #define SIPIN 30 |
13 | + | //sdiPin1 = 1 |
14 | - | #define DIPIN 31 |
14 | + | //sdiPin2 = 1 |
15 | - | #define CLKPIN 32 |
15 | + | //clkPin1 = 10 |
16 | - | #define LATCHPIN 33 |
16 | + | //clkPin2 = 10 |
17 | - | LEDStrip mystrip(DIPIN,SIPIN,LATCHPIN,CLKPIN); |
17 | + | //StartDelay = 0 |
18 | - | #define SPULSES 5000 |
18 | + | //EndDelay = 0 |
19 | - | #define STRIP_LENGTH 48 |
19 | + | //StrobeOn = 10 |
20 | - | #define BACKLIGHT 10 |
20 | + | //StrobeOff = 0 |
21 | - | byte BL = B10000000; // Black / Off |
21 | + | // Lightwand code generated by Phil Wright |
22 | - | #define SDssPin 53 //SD card CS pin |
22 | + | #include <avr/pgmspace.h> |
23 | - | int frameDelay = 10; // default for the frame delay |
23 | + | #include <SPI.h> |
24 | #include <Wire.h> | |
25 | #include <LiquidCrystal.h> | |
26 | - | //BacklightControl to save battery Life |
26 | + | #include <SdFat.h> |
27 | - | boolean BackLightTimer = false; |
27 | + | |
28 | - | int BackLightTimeout = 2000; |
28 | + | |
29 | - | int BackLightTemp = BackLightTimeout; |
29 | + | #define STRIP_LENGTH 32 // Total LEDs on this wand |
30 | //#int STRIP_WIDTH 6620 // Width on this strip | |
31 | - | //Stuff for the Keypad |
31 | + | int SS = 27; // Move the SS pin out of the way of the LCD Display (if installed) |
32 | - | int adc_key_val[5] ={ |
32 | + | int StripControl1 = 22; //Channel Select Wire for Dual Strip no. 1 |
33 | - | 30, 150, 360, 535, 760 }; |
33 | + | int StripControl2 = 23; //Channel Select Wire for Dual Strip no. 2 |
34 | - | int NUM_KEYS = 5; |
34 | + | |
35 | - | int adc_key_in; |
35 | + | |
36 | - | int key=-1; |
36 | + | |
37 | - | int oldkey=-1; |
37 | + | |
38 | boolean firstloop=true; | |
39 | - | File root; |
39 | + | |
40 | - | File dataFile; |
40 | + | |
41 | - | String m_CurrentFilename = ""; |
41 | + | |
42 | - | int m_FileIndex = 0; |
42 | + | |
43 | - | int m_NumberOfFiles = 0; |
43 | + | |
44 | - | String m_FileNames[200]; //yep this is bad, but unless you are going to have over 200 images on your lightwand.. |
44 | + | |
45 | } | |
46 | mybitmapblock; | |
47 | ||
48 | char buf[4]; | |
49 | int fileVersion; | |
50 | uint32_t bitmapOffset; | |
51 | int bitmapHeight; | |
52 | uint32_t bitmapWidth; | |
53 | int StartDelay; | |
54 | int EndDelay; | |
55 | int StrobeOn; | |
56 | int StrobeOff; | |
57 | byte VReversed; | |
58 | byte HReversed; | |
59 | ||
60 | ||
61 | SdFat sd; | |
62 | SdFile myFile; | |
63 | ||
64 | ||
65 | uint32_t readLong() | |
66 | { | |
67 | uint32_t retValue; | |
68 | myFile.read(buf,4); | |
69 | ||
70 | - | //Colour weights for the HL1606.. |
70 | + | retValue=(uint32_t)((byte)buf[0])<<24; |
71 | - | uint8_t HL1606highred = 100; |
71 | + | retValue+=(uint32_t)((byte)buf[1])<<16; |
72 | - | uint8_t HL1606highgreen = 100; |
72 | + | retValue+=(uint32_t)((byte)buf[2])<<8; |
73 | - | uint8_t HL1606highblue = 100; |
73 | + | retValue+=(uint32_t)((byte)buf[3]); |
74 | - | uint8_t HL1606lowred = 20; |
74 | + | |
75 | - | uint8_t HL1606lowgreen = 20; |
75 | + | |
76 | - | uint8_t HL1606lowblue = 20; |
76 | + | |
77 | ||
78 | int readInt() | |
79 | { | |
80 | - | void setup() |
80 | + | |
81 | myFile.read(buf,2); | |
82 | ||
83 | - | setupLEDs(); |
83 | + | retValue=(int)((byte)buf[0])<<8; |
84 | - | setupLCDdisplay(); |
84 | + | retValue+=(int)((byte)buf[1]); |
85 | - | setupSDcard(); |
85 | + | |
86 | - | BackLightOn(); |
86 | + | |
87 | } | |
88 | ||
89 | - | void setupLEDs() |
89 | + | |
90 | { | |
91 | - | ClearStrip(100); |
91 | + | byte retValue; |
92 | myFile.read(buf,1); | |
93 | ||
94 | - | void setupLCDdisplay() |
94 | + | |
95 | retValue=((byte)buf[0]); | |
96 | - | lcd.begin(16, 2); |
96 | + | |
97 | - | lcd.print(" *** DLW ***"); |
97 | + | |
98 | - | lcd.setCursor(0, 1); |
98 | + | |
99 | - | lcd.print("Initializing..."); |
99 | + | void writeRGB(uint8_t r,uint8_t g,uint8_t b,int nStrip) |
100 | - | delay(1000); |
100 | + | |
101 | if(nStrip==StripControl1) { | |
102 | - | //pinMode(BACKLIGHT, OUTPUT); |
102 | + | digitalWrite(StripControl2, LOW); |
103 | - | //digitalWrite(BACKLIGHT,LOW); |
103 | + | digitalWrite(StripControl1, HIGH); |
104 | } | |
105 | else | |
106 | { | |
107 | - | void setupSDcard() |
107 | + | digitalWrite(StripControl1, LOW); |
108 | digitalWrite(StripControl2, HIGH); | |
109 | - | pinMode(SDssPin, OUTPUT); |
109 | + | |
110 | SPI.transfer(g); | |
111 | - | while (!SD.begin(SDssPin)) { |
111 | + | SPI.transfer(r); |
112 | - | BackLightOn(); |
112 | + | SPI.transfer(b); |
113 | - | lcd.print("SD init failed!"); |
113 | + | |
114 | - | delay(1000); |
114 | + | digitalWrite(StripControl1, LOW); |
115 | - | lcd.clear(); |
115 | + | digitalWrite(StripControl2, LOW); |
116 | - | delay(500); |
116 | + | |
117 | } | |
118 | ||
119 | - | lcd.print("SD init done."); |
119 | + | void blank_strip() |
120 | - | delay(1000); |
120 | + | |
121 | - | root = SD.open("/"); |
121 | + | for(int x = 0 ; x < STRIP_LENGTH; x++) |
122 | buffer[x] = 0; | |
123 | - | lcd.print("Scanning files"); |
123 | + | |
124 | - | delay(500); |
124 | + | |
125 | - | GetFileNamesFromSD(root); |
125 | + | for(int LED_number = 0 ; LED_number < STRIP_LENGTH-1 ; LED_number=LED_number+2) { |
126 | - | isort(m_FileNames, m_NumberOfFiles); |
126 | + | |
127 | - | m_CurrentFilename = m_FileNames[0]; |
127 | + | int r=(((this_led_color>>16) & 0xff)>>1)|0x80; |
128 | - | DisplayCurrentFilename(); |
128 | + | int g=(((this_led_color>>8) & 0xff)>>1)|0x80; |
129 | - | |
129 | + | int b=(((this_led_color) & 0xff)>>1)|0x80; |
130 | delay(50); | |
131 | this_led_color = buffer[LED_number+1]; //24 bits of color data | |
132 | - | void latchanddelay(int dur) |
132 | + | r=(((this_led_color>>16) & 0xff)>>1)|0x80; |
133 | g=(((this_led_color>>8) & 0xff)>>1)|0x80; | |
134 | - | mystrip.latch(); |
134 | + | b=(((this_led_color) & 0xff)>>1)|0x80; |
135 | - | delay(dur); |
135 | + | delay(50); |
136 | } | |
137 | for(int i=0;i<STRIP_LENGTH;i=i+2) { | |
138 | - | void ClearStrip(int duration) |
138 | + | writeRGB(0,0,0,StripControl2); |
139 | writeRGB(0,0,0,StripControl1); | |
140 | - | int x; |
140 | + | |
141 | - | for(x=0;x<STRIP_LENGTH;x++) |
141 | + | |
142 | void setup() { | |
143 | - | mystrip.pushCmd(BL); |
143 | + | pinMode(SS, OUTPUT); |
144 | pinMode(StripControl1, OUTPUT); | |
145 | - | latchanddelay(duration); |
145 | + | pinMode(StripControl2, OUTPUT); |
146 | digitalWrite(StripControl2, LOW); | |
147 | digitalWrite(StripControl1, LOW); | |
148 | - | void MultiPush(int Cmd, int Cnt) { |
148 | + | |
149 | - | while(Cnt-->0) mystrip.pushCmd(Cmd); |
149 | + | SPI.begin(); |
150 | blank_strip(); | |
151 | ||
152 | - | int ReadKeypad() |
152 | + | |
153 | ||
154 | - | adc_key_in = analogRead(0); // read the value from the sensor |
154 | + | |
155 | - | digitalWrite(13, HIGH); |
155 | + | lcd.print("Lightwand Gen."); |
156 | - | key = get_key(adc_key_in); // convert into key press |
156 | + | delay(0); |
157 | ||
158 | - | if (key != oldkey) // if keypress is detected |
158 | + | |
159 | pinMode(StripControl1,OUTPUT); | |
160 | - | delay(50); // wait for debounce time |
160 | + | pinMode(StripControl2,OUTPUT); |
161 | - | adc_key_in = analogRead(0); // read the value from the sensor |
161 | + | pinMode(A0,INPUT); // THIS IS THE BUTTON |
162 | - | key = get_key(adc_key_in); // convert into key press |
162 | + | digitalWrite(StripControl1,LOW); |
163 | - | if (key != oldkey) |
163 | + | digitalWrite(StripControl2,LOW); |
164 | - | { |
164 | + | |
165 | - | oldkey = key; |
165 | + | if (!sd.init(SPI_FULL_SPEED, 27)) lcd.print("SDcard failed"); |
166 | - | if (key >=0){ |
166 | + | |
167 | - | return key; |
167 | + | |
168 | } | |
169 | - | } |
169 | + | void loop() { |
170 | // open file in current working directory | |
171 | - | return key; |
171 | + | |
172 | while(myFile.openNext(sd.cwd(), O_READ)) { | |
173 | myFile.read(buf,4); | |
174 | if(strncmp(&buf[0],"WAND",4)==0) | |
175 | - | // Convert ADC value to key number |
175 | + | |
176 | - | int get_key(unsigned int input) |
176 | + | |
177 | //if(!myFile.open("test.LSB",O_READ)) | |
178 | - | int k; |
178 | + | //{ |
179 | - | for (k = 0; k < NUM_KEYS; k++) |
179 | + | // lcd.print("open failed"); |
180 | // while(1) {}; | |
181 | - | if (input < adc_key_val[k]) |
181 | + | //} |
182 | - | { |
182 | + | |
183 | - | return k; |
183 | + | myFile.getFilename(&tmpbuffer[0]); |
184 | - | } |
184 | + | lcd.clear(); |
185 | lcd.print(&tmpbuffer[0]); | |
186 | - | if (k >= NUM_KEYS) |
186 | + | |
187 | - | k = -1; // No valid key pressed |
187 | + | //myFile.read(buf,4); |
188 | - | return k; |
188 | + | // if(strncmp(&buf[0],"WAND",4)==0) |
189 | // Serial.println("this is a bitmap file"); | |
190 | // else | |
191 | // Serial.println("this is not a bitmap file"); | |
192 | - | //The Main menu starts here... |
192 | + | |
193 | - | void loop() |
193 | + | fileVersion=readByte(); |
194 | bitmapOffset = readLong(); | |
195 | - | int keypress = ReadKeypad(); |
195 | + | bitmapHeight = readInt(); |
196 | - | if ( keypress == 1) //up key (step up through the filenames) |
196 | + | bitmapWidth = readLong(); |
197 | //cout << pstr("Height ") << bitmapHeight << endl; | |
198 | - | BackLightOn(); |
198 | + | //cout << pstr("Width ") << bitmapWidth << endl; |
199 | - | if (m_FileIndex > 0) |
199 | + | |
200 | StartDelay = readByte(); | |
201 | - | m_FileIndex--; |
201 | + | EndDelay = readByte(); |
202 | - | } |
202 | + | StrobeOn = readInt(); |
203 | - | else |
203 | + | StrobeOff = readInt(); |
204 | /* | |
205 | - | m_FileIndex = m_NumberOfFiles -1; //wrap round to the last file |
205 | + | cout << pstr("StartDelay ") << StartDelay << endl; |
206 | - | } |
206 | + | cout << pstr("EndDelay ") << EndDelay << endl; |
207 | cout << pstr("StrobeOn ") << StrobeOn << endl; | |
208 | - | DisplayCurrentFilename(); |
208 | + | cout << pstr("StroneOff ") << StrobeOff << endl; |
209 | - | delay(500); |
209 | + | */ |
210 | VReversed = readByte(); | |
211 | HReversed = readByte(); | |
212 | - | if ( keypress == 2) //down key (step down through the filenames) |
212 | + | |
213 | //cout << pstr("vReversed ") << VReversed << endl; | |
214 | - | BackLightOn(); |
214 | + | //cout << pstr("hReversed ") << HReversed << endl; |
215 | - | if (m_FileIndex < m_NumberOfFiles -1) |
215 | + | # |
216 | blank_strip(); | |
217 | - | m_FileIndex++; |
217 | + | post_frame(); |
218 | - | } |
218 | + | lcd.setCursor(0,0); |
219 | - | else |
219 | + | //lcd.print(Filename); |
220 | //lcd.print(" OK"); | |
221 | - | m_FileIndex = 0;//wrap round to the 1st file again |
221 | + | //sprintf(&tmpbuffer[0],"%ld",(long)bitmapWidth); |
222 | - | } |
222 | + | lcd.print((const String)&tmpbuffer[0]); |
223 | - | DisplayCurrentFilename(); |
223 | + | lcd.setCursor(0,1); |
224 | - | delay(500); |
224 | + | lcd.print("Waiting 4 Button"); |
225 | ||
226 | while(analogRead(A0)<900) { | |
227 | - | if (keypress == 4)//select key (send out the selected file) |
227 | + | delay(10); |
228 | } | |
229 | - | SendFile(m_CurrentFilename); |
229 | + | |
230 | /* | |
231 | for(int a=StartDelay;a>0;a--) { | |
232 | - | if(keypress == 0) //right key (frame delay +) |
232 | + | lcd.setCursor(0,1); |
233 | lcd.print("Start Delay "); | |
234 | - | BackLightOn(); |
234 | + | lcd.print(a); |
235 | - | if (frameDelay < 200) |
235 | + | lcd.print(" "); |
236 | delay(StartDelay*1000); | |
237 | - | frameDelay+=5; |
237 | + | } |
238 | - | } |
238 | + | */ |
239 | - | ShowFrameDelay(); |
239 | + | |
240 | myFile.seekSet(bitmapOffset); | |
241 | if(readLong()!=0L) sd.errorHalt("Bitmap offset incorrect"); | |
242 | - | if(keypress == 3)//left key (frame delay -) |
242 | + | |
243 | long filepos=0; | |
244 | - | BackLightOn(); |
244 | + | lcd.setCursor(0,1); |
245 | - | if (frameDelay > 5) |
245 | + | for(int x=0;x<bitmapWidth;x++) { |
246 | int bufpos=0; | |
247 | - | frameDelay-=5; |
247 | + | |
248 | - | } |
248 | + | if(x % (bitmapWidth / 16)==0) |
249 | - | ShowFrameDelay(); |
249 | + | |
250 | lcd.print("+"); | |
251 | } | |
252 | - | if (BackLightTimer == true) BackLightTime(); |
252 | + | |
253 | while(bufpos<STRIP_LENGTH) { | |
254 | ||
255 | myFile.read(&mybitmapblock,4); | |
256 | - | void BackLightOn() |
256 | + | |
257 | if(mybitmapblock.len>bitmapHeight) | |
258 | - | analogWrite(BACKLIGHT,255); |
258 | + | { |
259 | - | BackLightTimer = true; |
259 | + | lcd.clear(); |
260 | - | int BackLightTemp = BackLightTimeout; |
260 | + | lcd.print("Error Row "); |
261 | lcd.print(x); | |
262 | lcd.setCursor(0,1); | |
263 | - | void BackLightTime() |
263 | + | lcd.print("bufpos = "); |
264 | lcd.print(bufpos); | |
265 | - | if ((BackLightTemp <= 255) && (BackLightTemp >= 0)) |
265 | + | while(1) { |
266 | }; | |
267 | - | analogWrite(BACKLIGHT,BackLightTemp); |
267 | + | } |
268 | - | delay(1); |
268 | + | |
269 | filepos=filepos+4; | |
270 | - | |
270 | + | |
271 | - | if (BackLightTemp <= 0) |
271 | + | for(int j=0;j<mybitmapblock.len;j++) { |
272 | buffer[bufpos]=(long)mybitmapblock.r << 16; | |
273 | - | BackLightTimer = false; |
273 | + | buffer[bufpos]|=(long)mybitmapblock.g << 8; |
274 | - | BackLightTemp = BackLightTimeout; |
274 | + | buffer[bufpos++]|=(long)mybitmapblock.b; |
275 | - | analogWrite(BACKLIGHT,0); |
275 | + | } |
276 | if(bufpos>STRIP_LENGTH) { | |
277 | - | else |
277 | + | lcd.print("corrupt data"); |
278 | while(1) { | |
279 | - | BackLightTemp --; |
279 | + | }; |
280 | - | delay(1); |
280 | + | } |
281 | } | |
282 | post_frame(); | |
283 | delay(StrobeOn); | |
284 | - | void ShowFrameDelay() |
284 | + | if(StrobeOff>0) |
285 | { | |
286 | blank_strip(); | |
287 | - | lcd.print("Frame delay:"); |
287 | + | post_frame(); |
288 | - | lcd.setCursor(0,1); |
288 | + | delay(StrobeOff); |
289 | - | lcd.print(frameDelay); |
289 | + | |
290 | - | delay(500); |
290 | + | |
291 | - | DisplayCurrentFilename(); |
291 | + | } //if bitmap |
292 | myFile.close(); | |
293 | ||
294 | } // while | |
295 | - | void SendFile(String Filename) |
295 | + | |
296 | lcd.print("End of bitmaps"); | |
297 | ||
298 | - | lcd.print("Sending File"); |
298 | + | blank_strip(); |
299 | - | lcd.setCursor(0, 1); |
299 | + | post_frame(); |
300 | - | lcd.print(Filename); |
300 | + | |
301 | - | char temp[14]; |
301 | + | while(1) { |
302 | - | Filename.toCharArray(temp,14); |
302 | + | }; |
303 | ||
304 | - | dataFile = SD.open(temp); |
304 | + | /* |
305 | for(int a=5;a>0;a--) { | |
306 | - | // if the file is available send it to the LED's |
306 | + | lcd.setCursor(0,1); |
307 | - | if (dataFile) |
307 | + | lcd.print("End Delay "); |
308 | - | { |
308 | + | lcd.print(a); |
309 | - | ReadTheFile(); |
309 | + | delay(EndDelay*1000); |
310 | - | dataFile.close(); |
310 | + | }*/ |
311 | - | ClearStrip(100); |
311 | + | } |