Show Posts
Pages: 1 [2] 3
16  Using Arduino / Storage / SD Card bitmap read error/bug? on: September 23, 2012, 02:30:49 am
Greetings fellow tinkerers!

I'm having a doozie of an issue with a Dumilenove w/328p -- on Arduino IDE 1.0.1, using default SD library.  Also included is the FAST_SPI library for outputting the data to another bus once its been read from the card.  The result is the SAME with and without the FAST_SPI library/code.

***EDIT*** the problem is mostly solved, but evolved into a completely different glitch!  See below for new version/problem!

Power: I've tried with/without external power, same result.

Sketch:  Loading from SD card a bitmap file, 64 pixels wide by 100 pixels tall.  Trick is I only load 1 line of it at a time because I have so little ram to work with.  During testing I'm spitting that array out the Serial.print.

I think I may be running out of RAM and having a pointer go haywire somewhere in the background, but I can't debug to that level to understand.

The attached 'output' from the serial is a short version.  If I let it run long enough it either stops (fully crashes) or reads, but the 'for' loop in the main loop exceeds the original height (<100) and starts asking for row ++ forever.


Attached is the bitmap file, the code, and the output.


Code:
#include <FastSPI_LED.h>
#include <SD.h>

File myFile;
const int chipSelect = 4;
String fileNam = "3.bmp";
unsigned int height = 1;
unsigned long bitmapOffset = 0x36;
unsigned long filePosition = 0;

#define NUM_LEDS 64


int frameDelay = 1; //number of millis between animated frames


struct CRGB {
  unsigned char r;
  unsigned char g;
  unsigned char b;
};
struct CRGB *leds;  //I don't know what this does.


unsigned long CurTime = millis();

void setup()
{

  randomSeed(analogRead(0));
  Serial.begin(9600);
  //Serial.println("Start");

  //Serial.print(CurTime);
  fastSPIsetup();  //make the fastSPI library do its magic
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

void loop() {
  myFile = SD.open("3.bmp", FILE_READ);
  Serial.print("BitmapOffsetStart:");
  Serial.println(bitmapOffset,HEX);
  myFile.seek(0x16);
  height = myFile.read();
  myFile.seek(0xA);
  bitmapOffset = myFile.read();
  myFile.close();
  Serial.print("BitmapOffset:");
  Serial.println(bitmapOffset,HEX);
  Serial.print("Height:");
  Serial.println(height);

  
  for(int j=0; j<height;j++) //loop through each line in the file, then spit it out.
  {
    FSPIlineOut(j); //reads a line and displays
    delay(frameDelay);
  }

} //end void loop

void FSPIlineOut(unsigned int lineNo)
{
  myFile = SD.open("3.bmp", FILE_READ);
  //delay(100);
  filePosition = bitmapOffset;
  filePosition += (lineNo *(NUM_LEDS * 3) );
  myFile.seek(filePosition);//get to data
  delay(100);
  //memset(leds, 0, NUM_LEDS * 3);//blank the array
  Serial.print(lineNo);
  Serial.print(":");
  Serial.print(filePosition,HEX);
  Serial.print(":");
  Serial.print(myFile.position(),HEX);
  Serial.print(": ");
  for(int i=0; i < NUM_LEDS; i++)
  {
    leds[i].b=myFile.read();
    leds[i].g=myFile.read();
    leds[i].r=myFile.read();  
    Serial.print(leds[i].r,HEX);  
    Serial.print(",");
  }  
  Serial.println();
  if (!myFile){
    Serial.println("the card broke");

    //myFile.close();

  }//FastSPI_LED.show();   // write all the pixels out
  //delayMicroseconds(4);//to remove g-glitch (can be as low as 4)
  drawArray();
  //delay(frameDelay);//some actual display time
}





void drawArray() { //take the current pixel array, dump it to the leds, and shiftout
  //memset(leds, 0, NUM_LEDS * 3); //clear the led array
  //PORTD |= B00010000;// Set bit high
  //FastSPI_LED.show(); // shift out the array.
  //PORTD &= ~B00010000;// Set bit low - happens a bit fast for the NAND so above delay is required to de-glitch it
  //delay(1);
}








void fastSPIsetup()  //gets the fastspi library set up
{
  FastSPI_LED.setLeds(NUM_LEDS);
  FastSPI_LED.setChipset(CFastSPI_LED::SPI_WS2801);
  FastSPI_LED.setDataRate(3); //make the library work with 5v ws2801 strips


  FastSPI_LED.init();
  FastSPI_LED.start();

  leds = (struct CRGB*)FastSPI_LED.getRGBData();

}

^^above, note how it loads the file, seeks to the correct byte loaded from the bitmap header (0x36 is the position to find the first byte of the data, read 3 bytes per pixel until the end).  
The serial output is below:

The line after 'Height:100' is where the data is actually spilling out.
The left columns are 'line of the bitmap file read from the bottom': "address of the start of this line byte requested", and "address actually being read"
The first 16 lines (0-15) are correct, the remainder (ad nauseum) are broken...not reading anything of value, and spitting out -1 (no data found)
Particular interest is bitmap line 0: everything is correct, just the 'red' values are displayed, also, the other good read lines are a vertical slant, also read properly.

Code:
Initializing SD card...card initialized.
BitmapOffsetStart:36
BitmapOffset:36
Height:100
0:36:36: 0,FF,0,FF,0,0,FF,0,0,FF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF,FF,0,FF,FF,0,0,FF,0,FF,0,
1:F6:F6: FF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2:1B6:1B6: 0,FF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3:276:276: 0,0,FF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
<<redacted to reduce character count>>
14:AB6:AB6: 0,0,0,0,0,0,0,0,0,0,0,0,0,FF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
15:B76:B76: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
16:C36:C36: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FF,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
17:CF6:FFFFFFFF: FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,
the card broke
18:DB6:FFFFFFFF: FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,
the card broke

17  Forum 2005-2010 (read only) / Troubleshooting / 'if' equation always firing... on: January 15, 2010, 02:05:02 pm
I have a piece of code...

Code:
for (int i = 0; i < 8; i++) {
     temp = (j * 8) + i;
     temp3 = ledArray[temp];
     if (temp3 >= x ); {
     Serial.print(temp3, DEC);
     Serial.println(x, DEC);
     ledOut |= bit(i);
   }   //end if
    }  //next i
I had all the functions of temp3 = blabla embedded in the if statement, and took them out just to make sure.

Now...the way it works is I'm breaking an array of 24 into chunks of 8 for evaluation then shifting out to a shift register.
It used to work with just one shift register, but as soon as I made the array bigger it no longer works:
Serial Display:
Code:
01
01
01
01
01
01
01
01
After i, before shiftout
255
Zero is not greater than or equal to one, so it should not fire the if, but it does...8 times in a row.  No matter what data gets passed to this statement it doesnt seem to work.
255 is the decimal format of the bitwise setting of all 8 bits in the byte ledArray.

**back story, the whole point of this is I'm doing 3 bit (8 step) pwm control of an array of leds through shift registers by shifting at maximum speed.  I'm THIS close to giving up on the pwm concept - once the array gets as big as I hope (hundreds of leds) pwm will be unfeasable - but at this small prototyping stage I have some cool animations for an 8 led system...blargh.

Thanks in advance!  Please tell me I'm missing something stupid.
18  Forum 2005-2010 (read only) / Syntax & Programs / Re: arduino digital protractor on: December 12, 2009, 03:49:28 am
If its not too late, I'd highly suggest moving to something like an optical rotation (rotary) encoder rather than a pot.  http://hackaday.com/2009/08/27/nterfacing-a-digital-rotary-switch/

It removes the absolute and just measures referencial changes in angle - so you would have to calibrate to zero every time you turn it on, the upside is precision would go way up.

Rather than use a potentially expensive encoder, you can make your own and use a different optical encoder to read a printed larger strip.
19  Forum 2005-2010 (read only) / Troubleshooting / Re: Ambilight with Arduino Mega on: December 12, 2009, 03:04:33 am
That pcb/kit might be perfect for it.  The shiftbars would work well too.

The ledpainter uses a 15 dollar board, and 3 5 dollar texas instrument IC's...among a pile of other components, and might not support much current on each channel (no led bars probably)

The shiftbar is about 9 bucks a piece in small quantities, you would need 1 per led bar 'channel', somewhere between 2 and 8.

For a realistic amblight you only really need 2 channels for the effect (left and right), and more just amplifies the effect.  '4' bars would be perfect, 2 sides and 2 on top, which would mean you just use the built in arduino mega pwm.

You hook up a 12 volt source to transistors (mosfets if you start drawing more power), and use 5v from the pwm lines of the arduino to switch the transistors (or mosfets) on and off.
20  Forum 2005-2010 (read only) / Troubleshooting / Re: Math (pow) function problem on: August 22, 2009, 02:25:33 am
Yay! Dubble post! (you need it when you're as noob as me on this forum!)

Good news, it works!  Problem at 8 bit x 8 leds is its only about 10-20 hz updates, so it has obvious flicker.  Gonna reduce to 4 bit and clobber it! smiley-grin

Thanks again!
21  Forum 2005-2010 (read only) / Troubleshooting / Re: Math (pow) function problem on: August 21, 2009, 10:22:24 pm
Thanks AGAIN everyone for awesome info...

I'm gonna try banging those bits around tonight.  Seems that bitwise operand would run faster than a math pow function also smiley-grin

 Lastly: Any thoughts why the pow function is regurgitating goofy numbers?
22  Forum 2005-2010 (read only) / Troubleshooting / Re: Math (pow) function problem on: August 21, 2009, 07:25:59 am
Thanks again - so thats like bitset(), bitclear() in short form?
23  Forum 2005-2010 (read only) / Troubleshooting / Re: Math (pow) function problem on: August 21, 2009, 07:10:15 am
Thanks for the great quick replies:

My setup (can't copy paste as I'm using separate laptop from work computer to program during night shift) smiley-wink

pseudocode:

array[8] of leds, intensity from 0-255

for loop 1-255
shiftoutvalue = 0
for led 0-7
if(led[led] > loop, then shitoutvalue = shiftoutvalue + 2^loop
next led

shiftout(shiftoutvalue)
//(so if led 1 needs turning on, its 2^0 added, or 1)
//2^7 = 128, bit 7, yay.

next loop

Basically, count to 255, if the led's value is bright enough, show it during 'this' update

Trouble is the damn pow function is crapping the bed on me.

edit>> my pow function is to SET a bit, not to find out what a bit is.
24  Forum 2005-2010 (read only) / Troubleshooting / Math (pow) function problem on: August 21, 2009, 06:32:55 am
Greetings; haven't posted in forever.  

I'm trying to do something more complex than it needs to be - 8 bit pwm on an 8 bit 595 shift register.  I can shift quite well.  Shifting I can do.

Trouble is to calculate 'when' during the numerous updates each individual led should be lit.

Problem arises as such:  
I feed the pow function 2 variables, an int and 2
as in, value = pow(2,i);
it returns:
0 = 1
1 = 2
2 = 3
3 = 7
4 = 15...etc
Everything after '2^2' returns its correct value minus one.  
Am I crazy?  Should I be not feeding it directly 2,i, rather 2 variables?  The reference states it will take any float value.

Ultra confusion:  Serial.print(value); prints 1.00, 2.00, 3.00, etc
serial.print(value,DEC); prints 1 2 4 8 16...the correct numbers.
value is declared a double.
25  Forum 2005-2010 (read only) / Troubleshooting / Re: a question on pcb's? on: August 21, 2009, 06:52:58 am
silk...screening comes to mind. smiley-grin
26  Forum 2005-2010 (read only) / Interfacing / Re: Ways of interconnecting Arduinos on: December 12, 2009, 03:34:31 am
xbee's offer a full mesh infrastructure with just a little configuration, if a lot of confusion.

27  Forum 2005-2010 (read only) / Interfacing / Re: large rgb led matrix driver on: December 12, 2009, 02:04:59 am
Really you use the same chips but you have one for each channel, red, green, and blue, then link more chips for each channel to get more overall leds.

There is a maxim chip really good for driving leds at constant brightness with reduced parts...
http://www.maxim-ic.com/view_press_release.cfm/release_id/1158
they even do part samples!

That said -
28  Forum 2005-2010 (read only) / Interfacing / Re: Shifting out frequency on: October 03, 2008, 11:28:00 pm
Mem, thanks; that other thread is a great read.

I'm thinking it would go very well with a project I have planned for 'vanPOV'
29  Forum 2005-2010 (read only) / Interfacing / Re: Shifting out frequency on: October 03, 2008, 03:35:45 am
Depending on complexity, you could use a(nother) pile of digital logic ic's to make a huge led matrix...

bowdens hobby circuits has an interesting 'scalable 16 led scroller' that uses only digital logic.  Basically load 1 high bit, and start shifting.  To do what you are interested in just hook the carryout to the input on the first register.

The way I see it, output pins >clock, data, latch, and 2 inputs> button and carry-in

the arduino shifts 1 high bit out, then keeps shifting and listening to the carryout for the complete revolution.  This pin will also light your special led.  When it detects it, the arduino gets ready to load the bit back out.  simply check the button for a press during the time when the 'carry out' led is on.

I just wrote that, and decided a picture would be better...



with this design; shift speed wouldnt matter, as you wouldn't use shiftout, as you only shift 1 bit at a time, instead of the standard 1 byte (8 bits).
As a benefit, you could make cool animations using the standard shiftout to signify win or lose...


program>

start, shiftout x bits low to clear the field
loop like crazy
{shift 1 high bit out

loop until carryin=high or buttonpress = high
(shift 1 bit low
delay
check for button press
check for carryin)
end loop

if buttonpress then person hit button
 if carryin = high >>>win  //yay
 if carryin = low >>>lose  //nay

//loop ended, and we load a high bit at the start of the main loop...
}loop
30  Forum 2005-2010 (read only) / Interfacing / Re: Shifting out frequency on: October 03, 2008, 12:08:40 am
I hope double posting isnt a problem;

I guess I could make a software loop to count how many bytes it can shift out in a timed second...
Pages: 1 [2] 3