Showing posts with label mega. Show all posts
Showing posts with label mega. Show all posts

Tuesday


QuadCopter: Current Summary, Docs and Info 


The quad, controller, and camera


Flight Control Board

The flight control board is based on FreeIMU and built onto an Arduino Mega 2560 running MultiWii. The main goals were to build a customizeable and affordable quadcopter using mainly open source hardware and software, and learn a bit about how it all works. Bugs and design issues seem to have been worked out now, so it looks like this will be the base design for my board. Video

Since it is all open source, adding additional custom components to control lights, sound, servos, etc. is about as easy as it gets. For anybody already familiar with Arduino, it's just a matter of  choosing what customizations to add.

The top picture on the right shows the simplicity of  the FC board, using only a few modules. A previous mock-up of the board was scrapped due to some simple design flaws. The current version attempts to address some of those problems:

a: Although the shield fits tight, secure mounting is a must, and nylon standoffs are used to secure the shield to the Arduino.

b: Here I am using a cheap, single sided prototyping board, but we'll see how long it lasts...

c: The first mock-up used the female header pins as shown on the right of the bottom pic, but they aren't made for Arduinos (too thin), and caused I2C errors and subsequent crashes. The header pins shown on the left are thicker and fit snug every time.

d: The GPS module was left out since GPS nav won't be something I'll be using right away.

The ESCs connect to pins exposed on the top of the board, which are hard to see since the angle of the bottom pic purposely hides my shoddy looking soldering work. The Arduino gets fastened to the frame using rubber mounts taken from broken CD/DVD players to minimize vibration.


Notes:

FC Board:
The board is intially based on a FreeIMU board as mentioned previously, and is actually pretty simple to build at this point, with only 3 modules. The HMC5883L magnetometer module is connected to the aux. I2C lines of the MPU-6050, and running on 3.3V. An APC220 module is connected to the fourth serial port (serial3), and a GPS module can go on serial2 or via I2C if desired. The best part of the flight controller and quadcopter is that it is all based on open source software and hardware, so customization and prototyping like this is actually possible without spending huge amounts of money or time.

FC Board/Arduino Mega Connections:
pin2: front motor
pin3: rear motor
pin5: right motor
pin6: left motor
pin14: APC220 RX pin
pin15: APC220 TX pin
pin16: GPS RX pin
pin17: GPS TX pin
pin18: MPU6050 interrupt
pin20: MPU6050 SDA (I2C)
pin21: MPU6050 SDL (I2C)
pinA0: Voltage divider (battery monitor)
MPU6050: Aux SDA to HMC5883L SDA
MPU6050: Aux SDL to HMC5883L SDL


Main Parts:
1x Turnigy Talon carbon fiber frame
4x Turnigy 20Amp MultiStar ESCs
1x Turnigy ESC programmer
4x NTM Prop Drive Series 28-26A 1200kv/250W Motors
2x Slow Fly 8045 propellers
2x Slow Fly 8045R propellers
1x 4000mAh 3S LiPo battery pack
1x Arduino Mega
1x GY-521 Gyro Module (MPU-6050
1x HMC5883L Magnetometer module 
1x APC220 serial data wireless transceiver
Uses Modified XBox controller for RC (previous post)


XBox Controller:
Prev post. Uses the MultiWii RCSerial protocol
Quad can easily be controled by a PC via RCSerial protocol and APC220 transceiver

Frame/Physical Assembly:

Since the controller and FC board are both custom made, I had to code and then debug the controller during flight in some cases, and had no failsafe at the time. The initial assembly of the central parts of the frame used all nylon bolts. This was to prevent damage to the frame and motors when big crashes happened, since parts would usually break away before breaking or bending much. It currently uses a combination of metal and nylon connectors to provide rigidity and allow for some give on big impacts. As can be seen in the picture above, I have also made my own motor mounts.

ESC Calibration:

One of the problems I ran into in some of the first flights was individual motors cutting out seemingly randomly. The quad uses 20A Turnigy MultiStar ESCs, and gives a choice between slow-down of motors, and hard cutoff when the voltage is low. This caused a bit of frustration since the motors would start cutting out when the voltage was low, regardless of the setting via programming card.

I was confused by the MultiWii calibration code at first since, according to the ESC manual, it would basically just set the programming of the ESCs to the LiPo battery setting, and that hardly seemed like 'calibration':

ESC Programming:
a: Power ESCs on while receiving max throttle signal
b: These ESC will beep accordingly, move throttle to min to select what option to set in the programming 

The ESCs apparently use this interaction for calibration as well, and it made a big difference once I programmed them this way. The motors seemed to sound a bit smoother afterward, and they slow down nicely to force a landing once the battery is low.

Always remove your propellers before uncommenting this line in 'config.h':
#define ESC_CALIB_CANNOT_FLY 

Propeller Balancing:

Another important factor that was initially overlooked was propeller balancing. This made a big difference in the stability of the craft, as well as reducing vibrations. I followed this tutorial and had some good results on my first shot at it. Videos from the previous post show the vibration evident from unbalanced propellers, and a motor wire breaks in the second one, likely related to the vibration issues.

MultiWii Config and GUI:

The videos in the previous post were shot using the PID settings shown in the pic to the right and with the low-pass filter enabled for the MPU-6050 at 20Hz in 'config.h'. Higher values for the filter makes for 'tighter' controls, but is more susceptible to vibration and affects PID. Mitigating vibration issues should allow a higher setting. 

MultiWii Code:
Code base is MultiWii_dev_r1240
Uses slightly modified version, but can work with original:
  • Supports serial rc cmds with smaller payloads
  • Supports failsafe when using serial rc
  • Supports basic monitoring during flight via processing gui and existing transceiver (prev. post)
  • Still unsure whether to remove or work with test code to control a music player from alarms and controls, so left it in for now (alarm buzzer timing is changed)
  • Longer delay for ESC calibration code specific to MultiStar ESCs (see esc manual below)



Reference Material:
MultiWii - Code w/Modifications
MultiWii - Arduino Mega pin layout
MultiWii Wiki


Saturday

Quad/GoPro Camera Test

This video shows one of the first test flights using a GoPro camera strapped to my quadcopter. The camera is mounted using the included straps and is free to move around a little bit, so there is some movement and vibration evident in the video. Although way off balance, stability and power aren't much of a problem, but the batteries drain noticeably faster with the camera attached. The throtte is being hard limited to 75% for indoor testing.

Here the camera swings a lot so the video can be hard to watch:

Here the camera is mounted in a more stable way, top-side:


Thursday

Quad-Copter: Control and Feedback

  The quad has been working well using the MultiWii RCSerial protocol and custom XBox controller for basic flight controls, so it seemed time to add additional capabilities. The controller code now uses the same type of implementation used in the actual MultiWii code for building and sending RCSerial commands, so commands are easy to structure and send. The default failsafe code doesn't currently work with serial commands, so some simple modifications were made to accomodate the serial based control. Additional mods to the protocol are still being made to accomodate some additional commands and features as well.
   
  The flight control board has been updated with a GPS module and connections to monitor the battery voltage. Initial testing shows the quad can handle incoming commands while sending out data , so some initial coding was done using the Static Google Maps API and Processing to receive serial data from the quad, then display it on a map and plot the path taken during flight. 

  The sketch was designed to use the least amount of reasources possible, by passively listening for data to be sent periodically, and making use of the existing APC220 tranciever module on the FC board for communication. Here is a screenshot of the current iteration showing what it looks like in use. Here, the quad is actually sitting still, and the GPS is tracking around way off course for some reason, but it makes for a good demo of the tracking:


The above sketch is intended only for GPS functionality and basic status info, so will be kept fairly simple. It still needs work and requires some minor modifications to the MultiWii code. Right now it does the following:
- Displays location from GPS data
- Displays heading from magnetometer data
- Logs I2C errors with timestamps
- Plays warning sound if I2C errors are detected
- Zoom In/Out

Processing Sketch: 
MultiWiiGPS
Notes:
- Requires minor changes to MultiWii. See the included readme for info.
- Will work with any serial-data based transceiver
- If it stops getting maps, get an API key here
- Requires ControlP5 library
- Ubuntu users require this fix for audio to work
- Designed/tested with MultiWii_dev_r1240

  In addition to the GPS sketch, here is a link to the XBox controller code with initial integration of the RCSerial protocol. It is a work in progress, but the code is very stable, and it works great. See previous posts for details of the controller build.

Arduino Sketch:

Sunday

Quad-Copter: Free at last

The quad has come a long way in a short time since the previous post. After a fair bit of reading, adjusting and testing, I was finally able to get my custom flight control board working with the MultiWii software, and the initial results are better than expected.

I was able to get it working initially with the flight software by converting the data to PPM Sum at the receiver, and it worked fairly well in testing. This required the use of an additional microcontroller to receive the signal and convert it, so was not ideal.
Below is a short video showing the Quad-Copter while I attempt to learn the controls and work out some of the details on my custom controller. There are many things that still have to be tweaked, tuned, adjusted, and implemented but at this point, it is looking pretty promising for a custom rig:




After some more looking at the RCSerial protocol built into MultiWii, I was able to build it into my sketch and communicate directly with the flight control board using serial data via APC220 radio module, and my customized XBox controller. I had some troubles finding examples of direct control using the RCSerial protocol, so here is the working but incomplete sketch I have been using. In the next video, the flight control board is closer to completion, with the rf module, gyro/accel and magnetometer all soldered into place, and is using the 'Angle' and 'Mag' modes in MultiWii:




This mode is a lot easier to fly in, and after a few more flights like this, I'm comfortable that this setup is going to work pretty well, especially after some tuning and adjustments. As can be seen, the motor mountings are bent a bit, and the propellers also have some big cracks in them due to previous crashes, but it flies fairly well regardless. The throttle is being hard limited to 3/4 just for safety indoors, and I'm not getting close, so it will be interesting once this thing is outside. Additional features like low battery detection needs to be added, and some extras like GPS, a barometer, or an LCD screen may be added too, but a few bugs need to be worked out first. And yes, that is in fact a breadboard plugged into the Arduino Mega like a shield in the first video.


Details of flight controller on Summary Page:


Tuesday

Building a Quad-Copter

Why a quad-copter? Time spent working on various projects involving robotics and automation have led me to a single conclusion: Flying Robots!

My first searches on the subject turned up various projects that offer pre-built units you can simply buy, connect, and fly, but the point here is to build a unit with interchangeable and customizeable Arduino-based flight and radio controls, and hopefully learn a few things along the way. This will also allow me to build, tweak, add or modify any component as required.

After receiving the main components: frame, motors, ESCs, battery, etc., the first thing I did was test out a single motor and ESC using DIY speed control (An Arduino). I have some 20A Turnigy MultiStar ESCs, so connected the orange wire to pin 9, brown to ground, and left red unconnected. Then, with the power connected to the battery, and using the servo library, I was able to get the motor going by using servo.writeMicroseconds(700); and ramping it up to about 800 to hear the beep indicating it is ready to go, and then up to 900 to get the motor turning. Ramping it up higher increases the RPM, so it seems pretty simple to control. Later experimentation showed that starting at 1000 and ramping up from there seems to work the best.

Setup for spinning motors up and first liftoff:

The initial testing was done using commands sent over the serial port, and the next step was to use wireless remote control so, of course, I used the newly customized XBox controller from the previous post to acheive that. The controller sends a variable and/or a value, (such as "S 1000" for a speed of 1000) and reception is as simple as Serial.read(); etc. Since there are multiple rotors, two must spin the opposite direction of the other two, along with having reversed propellers. The ESCs come with a simple programmer, so direction is easily controllable electronically. Along with the servo library, I was able to spin up all four motors and get the quad-copter airbourne for the first time, if just for a few seconds.

Next is final assembly of the unit and to try for some DIY flight stabilization. My first attempts at flight control will use the Proportional-Integral-Derivative (PID) library which takes an input (pitch,roll, etc) and adjusts an output (motor speed) to maintain a constant reading. This is the same type of thing the line-following-junkbot code attempted to do. Currently, I have an MPU-6050 gyro/accellerometer module connected, which I hope is enough for some simple stabilization. Prior testing required the device to be strapped to the floor with a few inchess of slack, just enough for it to get airbourne, and the same setup will be used here. As luck would have it, my frame kit is lacking in nuts and bolts, so I had to scrounge some up from various broken electronics, and the "feet" are not connected.

First stabilization attempt

Above is the video showing the initial flight using untested and untweaked settings for the PID library and stabilization. Without PID enabled, the quadcopter lurches and jumps when the ropes pull tight, so this flight demonstrates that the stabilization is at least somewhat effective. Next will be to tweak and tune the PID, timing, and associated code for more stable flight, then probably on to controlling its movement.

This next video shows the quad once the PID settings are tuned a little bit better, as it demonstrates some actual stability. It is connected to the board via a large elastic, so whenever it pulls taught suddenly, there is a tendancy to jerk to the side, which the copter succesfully counteracts to a large degree. It took a fair bit of work to acheive this much stability, so a pre-bought flight control board is starting to look appealing.

More progress towards stabilization

Judging by its stability when under load and encountering some additional outside forces (from the tether), it may be time to start working on movement controls. They would simply adjust the balance point for the yaw and pitch, allowing me to direct its movements, and do some more fine tuning on the PID adjustements.

The MPU-6050 will be used in conjunction with an HMC5883L, which pretty much gives me the equivalent of the FreeIMU v0.4 board, minus the barometer. I've run the FreeImu GUI software, and succesfully calibrated my device, but the MPU-6050 library below seems to provide much more accurate readings, so I've been sticking with that. Since it works fine with the FreeIMU library, I attempted to use the MultiWii libraries, but have not had any luck. The sketch below is pretty basic, and only uses yaw, pitch, and roll readings for stabilization.


Libraries and Sketch:

Rough sketch
MPU-6050 library
Modified PID library


Hardware info on Summary Page



Monday

TMRpcm Arduino WAV/PCM Audio Playback Library Update

This is an update to my Arduino PCM/WAV audio llibrary detailed here and in previous posts. I now have the files hosted at GitHub, and I added an optional proof-of-concept library that enables RF (wireless) audio streaming capabilities to Arduino. Currently it will support two remote devices, but can be easily modified to stream to more. Arduino Mega likely needed for RF (wireless) audio host due to compiled size.

Source: here
Library Package: here

Thursday


JunkBot & XBox-RC Code Update:

Finally cleaned up the code for my JunkBot and XBox-controller based transmitter. I mainly went through and organized variables into arrays and loops as well as trying to simplify things where possible. The compiled controller code is 1KB smaller, and JunkBot code is about 4KB smaller than the last posted version. There are no real functional additons, but many improvements. Technically the JunkBot code should work with any Arduino-based RC unit that uses two motors for movement and a VirtualWire capable receiver.

The JunkBot is a small radio-controlled device made out of spare parts, and the main controller is an XBox controller with an Arduino Nano embedded inside, with an RF transmitter module attached. Details of both devices are in previous posts.




Monday

Over-the Air (RF) PCM Playback with NRF24L01+ and Arduino

Previous posts regarding the playback of wav files from an SD card were related to another project I am working on involving NRF24L01 radio modules. Since these are capable of around 20KB/s in a real-life scenario, I thought it would be worth a shot to try sending the audio over the air. Basically, I wanted to get feedback from an Arduino operating remotely in the form of sounds, but I don't have room for an SD card locally on the controller, and I also wanted the remote Arduino itself to be able to give feedback in the form of sounds when events are triggered or commands are received, etc.

This is the sketch I have been using to work out some of the details and the bugs. Right now it is geared up to work with two 'controllers' in that if you send the letter 'g' over the serial port to the 'transmitter', it will randomly play a beep on one of the three devices and continue randomly on as fast as it will go. (audio files not included) There is also a data transfer rate test that can be enabled, so one can see exactly how fast data is flowing. It will also play a sound file over the RF link, but thats kind of boring. The sketch is being posted mainly for my own reference, because in its current form I can't do much with it, and its not really useful for anything, but it does demonstrate the capabilities and how to use them.

This RF side of this also uses improved code for PCM playback, which I will likely include in the library previously posted. The timer is run at a minimum of double the actual sample rate, so as to maximize audio quality. Low quality 8khz sample rate sounds sound much, much better this way. This is very similar to the PCM libary, so sounds can be anywhere from 8-20khz sample rate, 8-bit, Mono, but it won't handle 20khz very well, since that is basically the max transfer rate. Speaker is pin 9 on Arduino Uno,Nano, etc, and 11 on Mega.

The system works using ack-payloads and interrupts to coordinate the data transfer and simultaneous playback. What is referred to as the 'transmitter' is actually set to PRX(primary reciever) and sends sound data in the form of ACK(acknowledgement) packets, with 32bytes payload. The 'receivers' just send out commands till one is answered, and then request the data as they need it. The 'transmitter' only sends out data in response to an incoming command.

 This could theoretically work on a larger number of devices, since it only uses a single data pipe at a time with different addresses for each device, but I don't really have any use for that.Change the data pipe to [1] before uploading to a second receiver.

The SD 'Transmitter' is a big sketch, and at the moment is just a bit big for the ATMega328, and I have been testing using a Mega 2560. The receivers are tested with a Nano328. Again, these are just rough sketches, but they work fairly well at this point: 

Controller/Receiver: here

SD Transmitter: here

This is the library for the NRF24L01+ I have been using: nrf24l01  Disclaimer: I did not author this library, it was found here . I just hacked in some extra code for testing which is required for this version of the sketch, and wanted to archive it for future reference.

Saturday

Asynchronous WAV/PCM: Arduino Audio Library Update:

 This library allows asynchronous playback of WAV files using only an Arduino, SD module, and a speaker.

 A little while ago, I decided to create a library for simple wav file playback using an Arduino, since I couldn't find any that fit my needs

Logical Functionality: 

I posted two previous versions of this libary, one that used a buffer, and one that used interrupts to load the data. Each had its tradeoffs, and neither were perfect. The interrupt based version had noticeable sound quality issues, and the buffering version could not be easily stopped during playback, or the volume adjusted, etc.
 The problem as I understand it, is that a read from the SD card will actually read 512 bytes at a time, so the buffering interrupt would not always complete before the music interrupt was set to trigger next. Since only 1 interrupt will trigger at a time, timing was an issue and so created other issues.

Searching through the datasheet for some functionality that would allow me to do what I wanted, I stumbled across mention of 'nested' interrupts. It took a little bit of time to figure out exactly how to use them in this application, but here is a brief overview of how the timer and interrupts work together:

OVF: This is an interrupt overflow vector that is triggered everytime the timer 'overflows'. (every cycle) Here, it reads a byte from the buffer into OCR1A, and therefore changes the pwm duty every cycle (@16khz)

COMPB: This is an interrupt compare match vector that is triggered when compare match is made during the timing cycle (TCNT1 == ICR1). This interrupt vector is used to read data into the buffers. Can be interrupted by other interrupts via 'nested interrupts'.

a: Interrupt vectors enabled: OVF, COMPB
b: When COMPB is triggered, it disables itself, but leaves OVF enabled. Global interrupts are automatically disabled while an interrupt completes. To enable nested interrupts, global interrupts are enabled manually before reading from the SD card.
c: If ready to buffer data, it begins (OVF can now interrupt COMPB while it bufferrs data)
d: COMPB completes, and re-enables itself to trigger again while it waits to buffer more data

Thanks to nested interrupts, I finally have what I wanted, with the basic functionality one would expect. I think the code can still use a bit of tweaking though, since I haven't fully tested its limits.

Updated Features:
- Sound Quality/Distortion issues have been resolved
- Uses a single timer (timer1)
- Asynchronous (interrupt driven) playback and buffering allows other code to run while music plays 

iTunes Conversion: 
a: Click Edit > Preferences > Import Settings
b: Change the dropdown to WAV Encoder and Setting: Custom > 16.000kHz, 8-bit, Mono

c: Right click any file in iTunes, and select "Create WAV Version"

d: Copy file to SD card using computer

Function Usage:
tmrpcm.play("filename"); //plays a file
tmrpcm.speakerPin = 11; // set to 11 for Mega, 9 for Uno, Nano, etc
tmrpcm.volume(1); //raises or lowers the volume: 1 or -1
tmrpcm.disable(); //disables the timer on output pin and stops the music
tmrpcm.stopPlayback(); //stops the music, but leaves the timer running

Individual Files:

Library Package:
TMRpcm.zip (OLD)
(now hosted on GitHub here)

Updated: 
Added Functionality:
Automatic detection of sample rate (8000 - 22000Hz)
WAV format verification
Memory buffer 300 bytes
Phase/Frequency-Correct and Fast PWM modes
 
Added functions: 
tmrpcm.isPlaying();  //returns 1 if music playing, 0 if not
tmrpcm.pause();  //pauses/unpauses playback
tmrpcm.pwmMode = 1; //set to 1 for phase/frequency correct mode, 0 for fast pwm 
tmrpcm.volume(0); //CHANGED from prev version, now uses either a 1(up) or 0(down)

Tested with: Arduino Nano/328 and Mega2560 
TMRpcm.zip  (OLD)

(Current version on GitHub here)

Monday

WAV/PCM Library Update:

 After reading into the capabilities of the Arduino timers, it seemed possible to generate an audio signal from PCM/WAV data using a single timer. Reading through the documentation, and looking at examples like the Timer1/Timer3 libraries, I found that I could use OCRnA to control duty cycle, ICRn and prescale for frequency, and use an overflow interrupt to update the value of OCRnA according to the defined SAMPLE_RATE, all with one timer.

How it works:

16-bit timer 1 is used for compatibility with different Arduino boards, but 16-bit Timers 3, 4, or 5 could be used on a Mega also.

The timer is set to Phase and Frequency Correct Mode, and set to run at a defined sample rate. The settings for prescale (TCCR1B) and input capture (ICR1) are what determines the frequency of the PWM signal when timer 1 is used, and OCR1A controls the duty cycle.

 An interrupt is attached to trigger every time the timer hits bottom. (Generally 16000 c/s) At this rate, an interrupt is generated 16000 times per second, and a new value is set for the duty cycle(OCR1A), then a new value is buffered for the next cycle.

In short, a signal is generated at 16000hz. The length of time each cycle stays turned on is determined by the value read in from the WAV/PCM file, which is updated every cycle.

No buffering: I am not sure of read speeds for SD cards, but testing indicates slightly higher sample rates can be achieved with no modifications. The SD library appears to default to SPI_HALF_SPEED, but will leave that inquiry for another day...

Whats new:

a: This version is completely controlled by interrupts, allowing other functions to run while music is playing. 
b: There is no longer a requirement for a large memory buffer, bytes are loaded as required
c: Added function to raise/lower volume: tmrpcm.volume(1);
d: Due to interrupt-driven playback, ability to stop/start music at will is added 

Data Format: unsigned 8-bit pcm, 16khz sample rate

iTunes Conversion: 
a: Click Edit > Preferences > Import Settings
b: Change the dropdown to WAV Encoder and Setting: Custom > 16.000kHz, 8-bit, Mono

c: Right click any file in iTunes, and select "Create WAV Version"

d: Copy file to SD card using computer

Function Usage:

 TMRpcm tmrpcm;              //Declare new object
 tmrpcm.speakerPin = 11;    //set to 11 for Arduino Mega, 9 for Uno, Duemilanove, etc
 tmrpcm.volume(1);             // 1 to raise volume, 0 to lower volume
 tmrpcm.play("filename");     // plays an unsigned 8-bit wav file from SD card
 tmrpcm.stopPlayback();     //stops playback
 tmrpcm.playing();               //returns true during playback, false otherwise

Updated Files / Source: 

Notice: This version has audio quality issues. See newer blog post for updated version

Source:
Example: music.ino  //Plays music while blinking a LED via the loop function 

Library Package:
TMRpcm.zip (Current version here)

Tuesday


Arduino WAV Playback Direct from SD Card 

*TMRpcm Library beta released*

The Problem: 

I wanted to be able to play a variety of sound clips using the Arduino, but could only find examples or libraries using program memory or other such methods. There are music shields you can get, but no examples for playing raw files from an SD card that I could find.

The Solution - Build a Library:
  
My library is directly based on the code shown at arduino.cc/playground/Code/PCMAudio as well as the library shown at: hlt.media.mit.edu/?p=1963, both of which use PROGMEM.
This is also the first library I have written, so there may be a few items slightly off, especially at this point in developing it.

First off, I had no idea how to make this work, but since it could work from progmem, why not from an SD card? Some sort of buffering would be needed for sure but how much, how to implement, etc. were some of the issues that had to be figured out.

Since I had no idea what I was doing exactly or how I was going to do it, I attempted to convert the files/data from the above links into char or byte format and saving it directly to a file on the SD card with no spaces, commas, etc. and playing it using the same method. It actually worked!

Once I proved the concept, then it was a matter of finding the best/simplest way to format the data for playback. Checking into the format of WAV files, I realized that they can be saved into a format that I can read directly using an Arduino with an SD card. There is a small header at the beginning of the file, but then it is basically raw data. The data can be saved in an 8-bit format (0-255), which can be read into the Arduino, and written directly to the registers with no modification.

The next problem is that I have never written a library, and Arduino programming is somewhat new to me, although I have dabbled in various programming languages for "fun" over the years. Following the tutorials found online, I was able to turn my sketch into a library.

For me, the easiest method was to use iTunes to convert the wav files, but any PCM file in the correct format will work:


Click Edit > Preferences > Import Settings

Then change the dropdown to WAV Encoder and Setting: Custom > 16.000kHz, 8-bit, Mono

Now you can just right click any file in iTunes, and select Create WAV Version

Then just copy the file(s) to an SD card attached to an Arduino, and check out the library below, with included example sketch.


How it works:

Both the above example and library this was based on use PROGMEM to store the variables which drive the PCM signal. Since we are reading WAV files directly from SD, we can save as many as the SD card will allow, with general disregard for file size.

The library uses timers and interrupts to create a signal that runs at 16000 cycles/second. The signal is controlled by the variables we read in from a file. The file is read into a small buffer, and playback is started. While interrupts control the playback, the second buffer starts filling up with data, using the spare cpu cycles between interrupts, and resumes playback once the first buffer is 'emptied'. Then the first buffer starts loading data again, while the second is 'emptied' and so on. This allows a continuous stream of data to be available for playback. Testing seems to indicate a minmum requirement for about 400 bytes of total memory for a steady stream and/or reasonable sound quality. (soundBuff = 200)

How to load data: In order to load the needed data onto an SD card, the wave file must be in the correct format, or converted using iTunes and the instructions above. Basically, this can be done using any computer with an SD slot, using any method that outputs wav files in the correct format.

Conclusion: This is totally possible, and it now works! The sound quality is low, but for simple sound clips, this is reasonable.

Example:

File(s) are placed onto the root of the SD card, then the following sketch is run:

 _________________________________________________________________

#include <SD.h>                      // need to include the SD library
#define SD_ChipSelectPin 53  //example uses hardware SS pin 53 on Mega2560
#include <TMRpcm.h>           //  also need to include this library...

TMRpcm tmrpcm;   // create an object (tmrpcm) for use in this sketch

void setup(){
 

tmrpcm.speakerPin = 10;
tmrpcm.soundBuff = 500; //uses 1KB memory. Min setting is about 200 (400 bytes)
 
pinMode(10,OUTPUT); //speaker pin
Serial.begin(115200);
  if (!SD.begin(SD_ChipSelectPin)) {  //see if card present and initialized:
    Serial.println("SD fail");  return;   // don't do anything more if not
  }else{   Serial.println("SD ok");   }

  tmrpcm.play("music"); //file "temple" plays when arduino powers up, or reset
}

void loop(){
  
  if (Serial.available() ){
    if (Serial.read() == 'C'){ 
      tmrpcm.play("music"); //sending a C to serial port starts playback
    }
  }
}
_________________________________________________________________

Modify the filenames for tmrpcm.play() to match your file.

Function Usage:

play("myFile");
stopPlayback();

Files/Source:

Developed using Arduino IDE 1.0.1
This is more or less just proof-of-concept currently, and will only work on Arduino Megas currently.


Source Code (OLD):
   TMRpcm.h
   Example: music.ino

Original Library Package (OLD):
   TMRpcm.zip

Current version on GitHub (download)
See the Wiki for updated usage and info



RF24Ethernet v2.0 Released - lwIP IP Stack Support + Direct TCP/IP connectivity without a RPi

RF24Ethernet v2.0 Released - lwIP IP Stack Support + Direct TCP/IP connectivity without a RPi   Better, faster & more reliable connectiv...