Show Posts
|
|
Pages: [1] 2 3 ... 6
|
|
2
|
Products / Arduino Due / Re: VGA library - now with TV output
|
on: May 04, 2013, 09:54:44 am
|
|
Stimmer,
VGA Library: stimmer-DueVGA-0.404-3-g86f6dc0
Color at 320x240
Adruino Pin 34, 35 --> Blue 36, 37, 38 --> Red 39, 40, 41 --> Green 42, 43 --> Hsync / Vsync
I'm using the Arduino Wifi Shield (R2) with onboard SD Card reader. I'm not actually using the Wifi functions at the moment.
SDFat Library: SdFatBeta20130207
|
|
|
|
|
3
|
Products / Arduino Due / Re: VGA library - now with TV output
|
on: May 02, 2013, 10:03:38 pm
|
|
Stimmer, I downloaded the library, but running into issues when also using the SDFat library to read my graphics off the SD Card. Any thoughts why these libraries conflict? Is there any potential for making them able to work together? It was possible previously with the PWM version.
I'd really like to use the VGA library because it's so convienient, but reading the graphics data off the SD card is absolutely needed (ie: I can't load the bitmap into the VGA library framebuffer without the SDFat library being initialized at the same time). I was hoping to take advantage of the speed increases you mentioned before, as well as the image stabilization using the additional timer.
Thanks for any info you can provide.
|
|
|
|
|
4
|
Products / Arduino Due / Re: VGA output
|
on: April 21, 2013, 07:52:05 pm
|
I reworked my code based off the REG_PWM version and am no longer having issues with the Serial connection. My code is able to load a bitmap graphic off the SD card, read the bitmap and DIB headers and resize any image to the desired 2D-array size. It has to down-sample from 24-bit color to 8-bit color, but still looks pretty good with only 256 color choices. Currently, I'm loading a background image to fit the 320x240x8 framebuffer. Then I load 2 smaller images to do some bit-blit. I'm using images that are 24x32 pixels (also down-sized and down-sampled from larger images). void readBitmap(char* filePath, byte** pictureBuffer,int bufferWidth,int bufferHeight) {
SdFile myFile; boolean openedFile = myFile.open(filePath,O_RDWR); if (openedFile) {
unsigned int FileSize=0; unsigned int Offset=0;
Serial.print("Reading "); Serial.print(filePath); Serial.println(" bitmap header..."); //Read Bitmap header for (int i=0;i<14;i++) { byte myByte=myFile.read(); Serial.print("Byte "); Serial.print(i); Serial.print(": 0x"); if (myByte<16) { //Pad with a leading zero, if needed. Serial.print("0"); } Serial.println(myByte,HEX);
//Bytes 2 through 5 are the file size if((i>=2) && (i<=5)) { FileSize=FileSize+(((int)myByte)<<(8*(i-2))); Serial.print("FileSize: "); Serial.println(FileSize); }
//Bytes 10 through 13 are the offset to the pixel data. if((i>=10) && (i<=14)) { Offset=Offset+(((int)myByte)<<(8*(i-10))); Serial.print("Offset: "); Serial.println(Offset); } }
Serial.print("Done reading "); Serial.print(filePath); Serial.println(" bitmap header.");
Serial.print("Reading "); Serial.print(filePath); Serial.println(" DIB header...");
unsigned int Width=0; unsigned int Height=0; unsigned int BitsPerPixel=0; //Read the DIB header for (int i=0;i<40;i++) { byte myByte=myFile.read(); Serial.print("Byte "); Serial.print(i); Serial.print(": 0x"); if (myByte<16) { //Pad with a leading zero, if needed. Serial.print("0"); } Serial.println(myByte,HEX);
//Bytes 4 through 7 are bitmap width in pixels if((i>=4) && (i<=7)) { Width=Width+(((int)myByte)<<(8*(i-4))); Serial.print("Width: "); Serial.println(Width); }
//Bytes 8 through 11 are bitmap height in pixels if((i>=8) && (i<=11)) { Height=Height+(((int)myByte)<<(8*(i-8))); Serial.print("Height: "); Serial.println(Height); }
//Bytes 14 through 15 are bitmap bits per pixel if((i>=14) && (i<=15)) { BitsPerPixel=BitsPerPixel+(((int)myByte)<<(8*(i-14))); Serial.print("BitsPerPixel: "); Serial.println(BitsPerPixel); }
}
int BytesPerPixel=((FileSize-Offset)/Width)/Height; Serial.print("BytesPerPixel="); Serial.println(BytesPerPixel);
Serial.print("Done reading "); Serial.print(filePath); Serial.println(" DIB header...");
Serial.print("Loading "); Serial.print(filePath); Serial.println(" bitmap pixels..."); myFile.seekSet(Offset+1);
byte buf[Width*BytesPerPixel];
for(int y=0;y<Height;y++) { //Serial.print("Loading Row: "); //Serial.print(y,DEC); //Serial.print(" / "); //Serial.println(Height,DEC);
//Serial.print("Pointer to FB[y][0] = "); //Serial.println((int)&FrameBuffer[y][0],HEX);
//Serial.print("Loading Pixel: "); //Serial.print(x,DEC); //Serial.print(" / "); //Serial.println(Width,DEC);
//Read the entire row of pixels all at once. //This is a major performance upgrade. myFile.read(buf,sizeof(buf));
//Convert the 3-bytes-per-pixel data into 1-byte-per-pixel format. for (int x=0;x<Width;x++){ byte red=buf[x*3]; byte green=buf[(x*3)+1]; byte blue=buf[(x*3)+2];
//Serial.print("Red = "); //Serial.println(red);
byte redBits = (byte)map(red,0,255,0,7); //Serial.print("RedBits = "); //Serial.println(redBits); byte greenBits = (byte)map(green,0,255,0,7); byte blueBits = (byte)map(blue,0,255,0,3);
pictureBuffer[(bufferHeight-1)-(int)(((double)y*(double)bufferHeight)/(double)Height)][(int)(((double)x*(double)bufferWidth)/(double)Width)]=(redBits<<5)+(greenBits<<2)+(blueBits); }
//The Bitmap file format pads every row to a 4-byte (word) //boundary. Calculate the padding, and skip it. int BytesInLastWord=((Width*BytesPerPixel)%4); int BytesOfPadding=0; if (BytesInLastWord>0) { BytesOfPadding=4-BytesInLastWord; } //Serial.print("Row should have "); //Serial.print(BytesOfPadding); //Serial.println(" bytes of padding.");
for (int i=0;i<BytesOfPadding;i++) { //Skip the padding byte. myFile.read(); } } myFile.close();
/* for (int y=0;y<Height;y++) { for (int x=0;x<Width;x++) { if (FrameBuffer[y][x]<16) { //Pad the output with a leading zero. Serial.print("0"); } Serial.print(FrameBuffer[y][x],HEX); Serial.print(","); } Serial.println(); } */
} else { Serial.print("Error opening file "); Serial.print(filePath); Serial.println(" for read."); }
Serial.print("Done loading "); Serial.print(filePath); Serial.println(" bitmap pixels.");
}//End readBitmap method I bit-blit the images using the following simple steps: void loop(void) {
if (millis()-starttime>100) { //Initialize our timer starttime=millis();
if (spriteDeployed==true) { //Erase the sprite by putting the background back. for (int y=0;y<32;y++) { for (int x=0;x<24;x++) { FrameBuffer[locationY+y][locationX+x]=background[y][x]; } } spriteDeployed=false; }
locationX=locationX+random(-5,6); if (locationX>320-24) { locationX=320-24; } if (locationX<0) { locationX=0; }
locationY=locationY+random(-5,6); if (locationY>240-32) { locationY=240-32; } if (locationY<0) { locationY=0; }
//Get the background for the new location for (int y=0;y<32;y++) { for (int x=0;x<24;x++) { background[y][x]=FrameBuffer[locationY+y][locationX+x]; } }
//Put Bit-Blit the sprite on the screen for (int y=0;y<32;y++) { for (int x=0;x<24;x++) { //The "And" (&=) operation allows for white background to be //transparent, and the black object to overwrite the background. FrameBuffer[locationY+y][locationX+x]&=Sprite[y][x]; //The "Or" (|=) operation allows the whte background to remain //transparent, while overlaying the color object on the black area. FrameBuffer[locationY+y][locationX+x]|=SpriteMask[y][x]; } } spriteDeployed=true; }
}//End loop This all works, except there's a slight flicker to the display. It's not bad, but bugs your eyes a little. The pixels seem to shift slightly left and right as the screen refreshes. It seems that the h-sync or v-sync timings must be off just slightly every once in a while. Is that possible with the interrupts? I'm trying to decide what to do to fix the image stability. Any thoughts?
|
|
|
|
|
5
|
Products / Arduino Due / Re: VGA output
|
on: January 23, 2013, 11:17:32 pm
|
I'm working on some code based off stimmer's modified code (320x240x8), but it seems that the Serial communication no longer works after setting up the timers. In the setup() method, I started the Serial at 9600, and then did println() thoughout the setup() method, and found this block of code causes it to stop working. What is it about this code that disables the serial output? REG_PIOD_OWER= 0xff; REG_PMC_PCER0= 1<<27; REG_PIOB_PDR = 1<<25; REG_PIOB_ABSR= 1<<25; REG_TC0_WPMR = 0x54494D00; REG_TC0_CMR0 = 0b00000000000010011100010000000000; // REG_TC0_CMR0 = 0b00000000000001101100010000000000; // this inverts hsync REG_TC0_RC0 = 1334; REG_TC0_RA0 = 1174; REG_TC0_CCR0 = 0b101; REG_TC0_IER0 = 0b00010000; REG_TC0_IDR0 = 0b11101111; NVIC_EnableIRQ(TC0_IRQn); Is there anything we can do to have this still work and have serial communication available? --edit-- I did some further debug and found that it works all the way up to the point of calling: NVIC_EnableIRQ(TC0_IRQn);
|
|
|
|
|
6
|
Products / Arduino Due / Re: Serial.print() of a 64-bit DOUBLE
|
on: January 19, 2013, 04:23:04 pm
|
I made those modifications to print.cpp and print.h, and it worked just great on my DUE. I am now able to display the true size of my 16 GB SD Card: Volume size (bytes): 15923150848 I didn't change the methods to size_t though, it worked fine without that change. (I did try it, and it threw a bunch of errors, so I left them as void). As you noted, the change does add about 8KB, but heck, I've got a DUE with 512K program memory, so I can spare the extra 8K. Woot.
|
|
|
|
|
7
|
Products / Arduino Due / Serial.print() of a 64-bit DOUBLE
|
on: January 19, 2013, 12:34:54 am
|
|
I've read in the Reference section that the DOUBLE data type on the Due is a 64-bit variable. Unfortunately, the Serial.print won't handle a 64-bit variable. I haven't been able to print out a uint64_t either.
Any ideas of how to print this?
I've looked into bit shifting the top 32-bits into an unsigned int, and then printing the high 32-bits followed by the low 32-bits, but apparently the bit shift operator defaults to a 32-bit operation as well.
The reason I'm trying to do this is because I stuck a 16 GB SD card into my wifi shield and can read it using the SD library, but it won't show the correct size of the SD card because it's so large. The unsigned int will only show up to ~4 GB. (0xFFFFFFFF = 4294967295 decimal).
Time to program the BigInt class?
|
|
|
|
|
10
|
Using Arduino / Programming Questions / Re: Stack size and sub-methods
|
on: September 20, 2011, 08:34:12 pm
|
|
Thanks Nick and westfw. I was happy to see some helpful conversation. That totally makes sense now that we're dealing with a pure software stack which would have to be managed by an OS for large processors. I guess I imagined some sort of hardware stack implemented in the chip architechture, or that they kept pointers to the high used heap address. Now I understand why it's not managed for embedded devices.
So, just for my education, how are variables allocated in the heap space? What I mean, is how is the memory managed? How do we keep track of which memory addresses are currently allocated to variables, and which addresses are free? Is that done by the compiler? If I were to attempt to write my own code to detect a heap / stack collision, is there a way to get the byte address of the highest used heap space memory?
Thanks.
|
|
|
|
|
11
|
Using Arduino / Programming Questions / Re: Stack size and sub-methods
|
on: September 10, 2011, 12:34:38 am
|
|
Currently I have two Arduinos. One is a Duemilenova DIP the other is an Uno SMD. Both are using the ATMega328p. 2kB SRAM, 32kB Program Mem. The Program Mem doesn't seem to be a problem, it's more the SRAM... It looks like the stack is getting pretty large.
End of SRAM = 0x08FF End of Regs = 0x00FF SRAM Size = 0x08FF-0x00FF = 0x0800 = 2048 Bytes (2kB)
Stack Pointer = 0x0606 Stack Size = 0x08FF- 0x0606 = 0x0259 = 761 Bytes Heap Space = 0x0800-0x0259 = 0x05A7 = 1447 Bytes
Why isn't there some sort of protection to prevent the heap and stack from overlapping? Don't they protect against this on other processors? You'd get some sort of error like a stack-overflow or something on a PC. Is that too much work on a uC?
|
|
|
|
|
12
|
Using Arduino / Programming Questions / Re: ? How to graph data and curves?
|
on: September 10, 2011, 12:03:40 am
|
|
You can get the QT libraries for C, if that's your desired language. Granted, C is probably the toughest language to do graphics easily in.
You can easily write some java code with the standard packages in eclipse to draw your own graphs. You probably could google for a graphing java class, and come up with some source that's ready to go.
I've used Visual Basic to draw graphs before, super easy.
Excel can do it, if you don't mind VBA, and don't need it real-time.
|
|
|
|
|
13
|
Using Arduino / Programming Questions / Stack size and sub-methods
|
on: September 09, 2011, 11:25:23 pm
|
|
Hi Folks, I've been writing a fairly large sketch which has functions that call other functions several times deep. They're not recursive, but say about 7-subroutines deep. From what I understand about the stack, is that all the register values are pushed onto the stack each time a new method is called. Are all the local variables from the calling method also pushed onto the stack as well? They must-- I don't see how we'd keep track of local variables otherwise.
I understand that the stack starts at the highest SRAM address and grows downward, whereas the regular Data Memory starts just after all the External IO Registers and grows upward. Eventually, as SRAM usage grows, the heap space and the stack space collide.
The reason I ask is because once I reached a certain method-depth, the program ceases to function correctly... if at all. I assume that the heap data has over-written part of the stack, and thus a return value is no longer valid. From my previous programming experience, it was good practice to use local variables wherever possible... but with such limited stack space, and no warning that stack corruption is taking place, I'm unsure if there's a better way to handle this.
Is there a way to set a maximum stack size? Or to limit the area of SRAM which can be used for the heap? How do the advanced users out there deal with these issues?
|
|
|
|
|
14
|
Using Arduino / Programming Questions / Re: How to extract server/domain from a URL in char[]
|
on: July 01, 2011, 04:30:27 pm
|
The problem here is that people are used to software fixing their URLs for them. Check out wikipedia's article on URLs: http://en.wikipedia.org/wiki/Uniform_Resource_Locator#SyntaxDepending on the context of the URL, programs attempt to fix the "scheme" parameter if it is missing. This works well in contexts that you know what the usual method of retriving that data type is, and which port that usually happens on. ie: web-browsers usually look on the http port 80 for web page data. Browsers will automatically pre-pend the http:// to the domain name, and see if it gets a response. This doesn't always work though, if you're really looking for a FTP site, for example. So really, unless you know the context, not having the "scheme" parameter indicates a malformed URL. Check out http://en.wikipedia.org/wiki/URL_normalization. It's a good list of things you should do too, if you want it to work at least good (poorly?) as web-browsers do. That being said, your spagetti code is probably on the right track. You'd probably have best luck using the String library. Otherwise, checking individual array location gets to be a pain. The string library will let you use a substring function too, so you'll easily be able to search for the "http://" and the "www." strings and remove them from the beginning of your complete URL. There are quite a few protocols that you'd need to check and remove from the beginning, but getting all the standard ones might be good enough to do the job. Here's a list of the scheme parameters you may need to parse out: http://en.wikipedia.org/wiki/URI_schemeOnce those are removed from the front, simply search for the first "/" you find. Everything before that will be the domain. Everything else (including the "/") will be the rest of the URL, obviously. Good Luck, parsing sucks.
|
|
|
|
|