Loading...
  Show Posts
Pages: [1] 2 3 ... 6
1  Products / Arduino Due / Re: VGA library - now with TV output on: May 06, 2013, 07:15:19 pm
Stimmer,
   Thanks for the advice.  Switched to

#define USE_SAM3X_DMAC 0

in the SDFat library, and everything works perfectly now.
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). 

Code:
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:

Code:
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?  

Code:
 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:

Code:
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:

Code:
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?
8  Products / Arduino Due / Re: Arduino Due Wifi example not working on: January 18, 2013, 11:56:38 pm
How exactly do we get the code from the repository and build the library until it's released somewhere officially?
9  Using Arduino / Programming Questions / Re: how can I add a second function to the same switch? on: September 20, 2011, 08:44:13 pm
You could attach an interrupt to your function.  That way the function gets called automatically when the button is pushed / let go.

http://arduino.cc/en/Reference/AttachInterrupt

Simply use millis() to record when the button state changes (is pushed / let go).  Subtract the two times.  Then do a specific action based on the elapsed time.  Reset the timers whenever the button is let go... after an action is done.
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#Syntax

Depending 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_scheme

Once 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.
15  Using Arduino / Networking, Protocols, and Devices / Re: Checksum for RF transmission on: June 07, 2011, 01:58:16 pm
Bitwise negation.  http://arduino.cc/en/Reference/BitwiseXorNot

~0x00 = 0xFF

You can think of a byte as signed or not.  It doesn't really matter, it's just your interpretation of the bits.  In this case, I treat it as unsigned because it's declared as a byte type.
Pages: [1] 2 3 ... 6