virtual size_t write(uint8_t);
using Print::write; // pull in write(str) and write(buf, size) from Print
size_t HardwareSerial::write(uint8_t c)
{
int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
// If the output buffer is full, there's nothing for it other than to
// wait for the interrupt handler to empty it a bit
// ???: return 0 here instead?
while (i == _tx_buffer->tail)
;
_tx_buffer->buffer[_tx_buffer->head] = c;
_tx_buffer->head = i;
sbi(*_ucsrb, _udrie);
return 1;
}
virtual void write(uint8_t);
using Print::write; // pull in write(str) and write(buf, size) from Print
void HardwareSerial::write(uint8_t c)
{
while (!((*_ucsra) & (1 << _udre)))
;
*_udr = c;
}
Print
virtual void write(uint8_t) = 0;
virtual void write(const char *str);
virtual void write(const uint8_t *buffer, size_t size);
/* default implementation: may be overridden */
void Print::write(const char *str)
{
while (*str)
write(*str++);
}
/* default implementation: may be overridden */
void Print::write(const uint8_t *buffer, size_t size)
{
while (size--)
write(*buffer++);
}
Retroplayer:
Of course, I would need to go further and provide a way to use the other hardware serial ports on a Mega.
This is taken care of by providing a constructor which accepts a HardwareSerial. You can pass in Serial, or Serial2 or any other hardware serial port that your Arduino has.
Here is what I have come up with. I am at work and did it all over lunch so I have not had a chance to test it. I basically just stripped the softwareserial library to only it's useful bits and threw in my code. I am attaching it because it is too large.
I kept the write() method public so that I could just write the supposedly unsupported commands. The constructor takes a tx pin and a busy pin. I am not currently using the busy pin yet, but will add that in later.
The baudrate and all values are pre-calculated for 4800 buad at 16MHz in order to get rid of all of the tables. I may go back and correct that to allow other frequencies to be used. But the baud rate will always be 4800 for this module, no matter what. I think only tx_delay and transmit_start are affected by a change in CPU frequency.
I left in #include <Stream.h> but I don't think I need it now that I ripped out all the read and print functions.
If you notice any glaring errors or anything I can remove or simplify, please let me know.
Doh... I forgot to add the serMP3:: to my functions. I am aware of that and fixing it. But, any other errors you see, let me know, please.
I also added a begin function again that accepts an initial volume level. This function also stops anything that is playing because the module has a tendency to start playing a random file from the root folder on initial power up.
Not exactly sure what I will do with the busy pin, since really the only time I would need to check it would be when it is playing a MP3 and you try to play another. I think I will just add a public funciton to check it.
Perhaps in the play function, I can check if it is busy and if so, stop the current MP3 and play the new one.
But then I need to account for when the busypin is not being used in an application.
ok, got home. Got the library working the way it should. Set up a simple example program to show it off and it works. But, for some reason if I pick an MP3 that doesn't exist, it always plays the last one it was playing.... grr....
My serial commands will look like this:
P001 or p001 = Play 001.mp3
s or S = stop
V31 or v31 = set volume at 31
= volume up
= volume down
r or R = resume
h or H = pause
C02 = change to 02 folder
Doing some debugging, I learned that if you point to an MP3 that doesn't exist, it switches to random play and plays whatever. Trying to figure out how I can prevent that.
Looking for a good way to handle the multibyte serial entries. Ideally, I would like P1,P01, and P001 to all be the same. Same with volume and folder commands. I know I could do a ton of OR conditions and loops, but there is an easier way, I am sure.
I have attached the finished library and my example code.