Show Posts
Pages: [1]
1  Forum 2005-2010 (read only) / Syntax & Programs / Re: Simple Fifo Library on: March 08, 2010, 07:27:31 pm
I just tried the example, one quick fix:

The dequeue for loop checks sFIFO.count() on each iteration.  Since we are reading one value on every iternation, count() will decrease by 1.  So i and count will progress like so:

i = 0, count() = 5
i = 1, count() = 4
i = 2, count() = 3
i = 3, count() = 2

So the loop will only read the first 3 points from the FIFO.  It's easily fixed by storing the initial count() value in another variable.  I also found it useful to print the count() value to the serial port.

I'll plug it in to my code and do a more comprehensive test next.

-RB
2  Forum 2005-2010 (read only) / Syntax & Programs / Re: Simple Fifo Library on: March 06, 2010, 02:28:30 am
That makes sense.  Thank you for taking the time to explain.  I'll stick to 256 elements or less.

-RB
3  Forum 2005-2010 (read only) / Syntax & Programs / Re: Simple Fifo Library on: March 06, 2010, 12:08:38 am
Quote
The code AlphaBeta provided may not work reliably in this context.  I think interrupts may need to be disabled when accessing and adjusting numberOfElements.

Can you explain how this is unsafe?  Doesn't the HardwareSerial library do the exact same thing to move data from the UART_RX ISR to be read in the main loop?

Thanks!
-RB
4  Forum 2005-2010 (read only) / Syntax & Programs / Re: Simple Fifo Library on: March 05, 2010, 09:37:44 am
This looks like what I need.  I took a quick look and I think all I would need to add is the 'flush' method to reset the pointers to 0.

I'll try this out tonight.  Thanks for your help!

-RB
5  Forum 2005-2010 (read only) / Syntax & Programs / Re: Simple Fifo Library on: March 05, 2010, 03:09:16 am
Similar to how the rx buffer works in hardware serial, I would like the write to the FIFO in an ISR and read from the FIFO in the main program loop.  Right now I want to write adc input data in an ISR and operate on it in the main loop.

A byte or character FIFO should allow me to move data this way.
6  Forum 2005-2010 (read only) / Syntax & Programs / Simple Fifo Library on: March 04, 2010, 11:17:48 pm
I need a library that will allow me to easily create byte FIFO's in my code.  The Arduino HardwareSerial library uses such a FIFO to store RX characters (struct called ring_buffer).  Unfortunately I'm not quite sure how to copy this functionality into a new library.  I think I need a header file like this:
Code:
struct ring_buffer;

class ByteFifo
{
  public:
    void write(uint8_t);
    uint8_t read(void);
    uint8_t available(void);
    void flush(void);       
};
I get confused when it comes to writing the code for the methods in the class.  I can copy the ring_buffer struct as well as the store_char functions from HardwareSerial, but I'm not sure how to pass around the buffer variable (or pointer?).  In HardwareSerial a ring_buffer is created for each UART.  I would like my library to create a new ring buffer for each instance.  

I'm also not sure what to include in the constructor.  Ideally I'd even be able to define the FIFO depth when I create it, but that isn't absolutely necessary.  Here is my current ByteFifo.cpp:
Code:
#define RX_BUFFER_SIZE 128

struct ring_buffer {
  unsigned char buffer[RX_BUFFER_SIZE];
  uint8_t head;
  uint8_t tail;
};

inline void store_char(unsigned char c, ring_buffer *rx_buffer)
{
  int i = (rx_buffer->head + 1) % RX_BUFFER_SIZE;

  // if we should be storing the received character into the location
  // just before the tail (meaning that the head would advance to the
  // current location of the tail), we're about to overflow the buffer
  // and so we don't write the character or advance the head.
  if (i != rx_buffer->tail) {
    rx_buffer->buffer[rx_buffer->head] = c;
    rx_buffer->head = i;
  }
}

// Constructors ////////////////////////////////////////////////////////////////
ByteFifo::ByteFifo()
{
  _rx_buffer = rx_buffer;
}

// Public Methods //////////////////////////////////////////////////////////////
void ByteFifo::write(uint8_t c)
{
  store_char(c,_rx_buffer);
}

uint8_t ByteFifo::read(void)
{
  // if the head isn't ahead of the tail, we don't have any characters
  if (_rx_buffer->head == _rx_buffer->tail) {
    return -1;
  } else {
    unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
    _rx_buffer->tail = _rx_buffer->tail + 1;
    _rx_buffer->tail %= RX_BUFFER_SIZE;
    return c;
  }
}

uint8_t ByteFifo::available(void)
{
  //return (RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % RX_BUFFER_SIZE;
  uint16_t tmp = (_rx_buffer->head + RX_BUFFER_SIZE - _rx_buffer->tail);
    tmp %= RX_BUFFER_SIZE;
    return (uint8_t)tmp;
}

void ByteFifo::flush()
{
  // don't reverse this or there may be problems if the RX interrupt
  // occurs after reading the value of rx_buffer_head but before writing
  // the value to rx_buffer_tail; the previous value of rx_buffer_head
  // may be written to rx_buffer_tail, making it appear as if the buffer
  // don't reverse this or there may be problems if the RX interrupt
  // occurs after reading the value of rx_buffer_head but before writing
  // the value to rx_buffer_tail; the previous value of rx_buffer_head
  // may be written to rx_buffer_tail, making it appear as if the buffer
  // were full, not empty.
  _rx_buffer->head = _rx_buffer->tail;
}

Any help is appreciated.
7  Forum 2005-2010 (read only) / Interfacing / Re: Is Deviceprint immpossible to make work? on: March 29, 2010, 05:27:10 pm
Have you looked at this Fat16 library?

http://code.google.com/p/fat16lib/

I moved over to it and have been successful so far.

-RB
8  Forum 2005-2010 (read only) / Interfacing / Re: Is Deviceprint immpossible to make work? on: May 13, 2009, 10:25:15 pm
I think I am having similar issues writing to my SD card.  DevicePrintDemo returns the following error:

"Error  Couldn't initialise microfat"

I then tried the dptest.pde posted elsewhere (closing the IDE, removing the uFAT libraries from the library directory) and it worked.  

I then moved the libraries from the dptest directory into the libraries directory and tried dptest again - it works.

I then retried DevicePrintDemo (with the dptest libraries) and it fails as above.

Then I modifed the section of DevicePrintDemo that throws this error to match the dptest code, as follows:

Original DevicePrintDemo code:
Code:
 if (!microfat2::initialize(sectorBuffer, &mmc::readSectors))
  {
    error_P(PSTR("Couldn't initialise microfat"));
  }
dptest code:
Code:
int ufres = microfat2::initialize(sectorBuffer, &mmc::readSectors);
  if (ufres != 0)
  {
    print_P(PSTR("Couldn't initialise microfat: error code "));
    Serial.print(ufres, DEC);
    error_P(PSTR("\r\n"));
  }
and the modified DevicePrintDemo works (still with the dptest libraries in the Hw/library directory).

Finally - I put the original uFAT libraries back into the HW/libraries directory... (drumroll) and now the modified DevicePrintDemo as well as dptest result in this error:
"Couldn't initialise microfat: error code 1Error "

If I change DevicePrintDemo back to the original code for checking this error - it now magically works.  argh.

Question 1 - Are DpTest and DevicePrintDemo based on the same library code?  Should they both work with the uFAT libraries in the library ZIP?

Question 2 - What is the difference between the two methods for initializing microfat?  Why does only one work with the dptest library?

Question 3 - I have no idea why the DevicePrintDemo with the uFAT libraries started working after all of that.  Let me know if you can explain.


I'm a beginner - any advice on uFAT debug or dealing with library issues is appreciated.
9  Forum 2005-2010 (read only) / Development / Re: Disable Serial (hardwareserial.cpp) on: February 20, 2010, 07:12:04 pm
Roy -

I also need to create my own serial interrupt routine.  Thank you for sharing you solution.  Do you think there's a chance of implementing your WProgram.h idea in the next version of the IDE?

-RB
10  Forum 2005-2010 (read only) / Interfacing / Re: Interrupt Driven Serial on: February 07, 2010, 02:25:42 pm
Thank you for the clarification.  Regarding the transmit side of the hardware serial interface:

I noticed the ATmega includes a 'Transmit complete interrupt' for the USART.  I think I could use this interrupt as follows:

* Create a buffer to hold multiple transmit characters
* Use this interrupt to call a function send a character from my buffer to the transmit data register.
* Monitor the buffer fullness in the main loop to make sure it doesn't overflow/underflow

Is this correct?

Thanks,
RB
11  Forum 2005-2010 (read only) / Interfacing / Re: Interrupt Driven Serial on: February 07, 2010, 12:26:21 pm
Hi Will,

I am also interested in interrupt based serial for the HW port(s) - I am using the Mega.  Thanks for the post, let me know if you make any progress on adding this capability.

-RB

UPDATE: I looked through HardwareSerial.cpp in the cores/Arduino folder and it appears that receiving serial characters is already based on HW interrupts.  The default buffer size is 128 characters.  Is this correct?
12  Forum 2005-2010 (read only) / Exhibition / Re: FileLogger on: May 13, 2009, 07:56:14 pm
Will this library tolerate the following scenario?

1 - I write several lines to the SD Card
2 - I remove the SD card and re-insert it
3 - I write more lines to the SD Card

I am trying it with your example code, and I get file errors when I try to write after re-inserting the card.  The only way to fix it seems to be resetting the Arduino.

Thanks.
13  Forum 2005-2010 (read only) / Exhibition / Re: SD/MMC From the ground up on: May 12, 2009, 08:40:25 pm
How does this solution compare to the FileLogger library?

http://code.google.com/p/arduino-filelogger/

One difference is that with FileLogger you have to create the file, but you don't have to pre-allocate the size.  

I'm curious as to the difference in data bandwidth and code space.

NOTE: They both use 'mmc' sub-files which are not the same, so if you want to try both be aware of this.
Pages: [1]