Archive for the ‘arduino’ Category

Moving code from Arduino to Raspberry Pi

Thursday, May 31st, 2012
Photo: Hello world, using the WiringPi library to control an LED display.

Photo 1: Hello world, using the WiringPi library to control an LED display.

To celebrate getting the GPIO working using WiringPi from Gordon Henderson I thought I’d have a quick look at the difference between running some code on an Arduino compared to running almost the same code on a Raspberry Pi (RasPi).

It is worth noting now that the setups I’ve been using to test with are all powered from a separate 3.3V supply with the grounds linked. Nothing is being powered via the RasPi itself to avoid drawing too much current should I make a mistake. When working with the RasPi you should be careful as the RasPi will not take kindly to static discharge, connecting things backwards or the wrong voltage levels.

The really great thing about Gordon’s library is that by using it I am able to transfer Arduino code to the RasPi with only a few simple changes. Obviously not everything in the Arduino libraries are present, but the basic I/O manipulation is plenty for some simple applications.

MAX6675 thermocouple interface example

The MAX6675 from Maxim is an SPI Bus based thermocouple convertor that I built a breakout board for a while back. You can find out more information about that project in this earlier post.

As a simple test I took the basic example from the MAX6675 thermocouple interface library and adapted it to run with the WiringPi library on the RasPi.

I initially ported the example and library to C as the WiringPi was in C and I had a couple of issues compiling mixed C and C++ properly. After a bit of investigation I found that when explicitly including the libraries as C the compiling problems go away. Below is an example of how to modify the wiringPi.h file to ensure it is included as C and not C++. Gordon has said he will make this change to the library on the next release. Once I had sorted out the makefile to use g++ rather than gcc I was able to compile and link successfully.

Listing 1: Explicitly declaring a header file as C


 #ifdef __cplusplus
 extern "C" {
 #endif
  
 // wiringPi.h Code goes Here 
 //  or 
 // #include <wiringPi.h>

 #ifdef __cplusplus
 }
 #endif

While compiling and linking of the example was now okay, the next problem was that when run, the program just exited with a “Segmentation Fault” (segfault). I didn’t even see the error message when running as root with sudo, it was only when running as the standard user (pi) that it became apparent that something was wrong with the software rather than the hardware.

When I had run previous examples as the standard user I would see a permissions related error complaining that the program could not access the “/dev/mem/” device. This error comes from the part of the WiringPi library that sets up memory access to the hardware registers in the Broadcom BCM2835. This clue told me that the wiringPiSetup routine was not being run. This in turn showed me that the global object representing the temperature sensor was being constructed before the WiringPi library was being setup.

The solution to this particular problem was simple enough. I edited the MAX6675 library so that it calls wiringPiSetup directly when initialising. I also set an internal flag if this succeeds. In addition to this I modified the methods to exit with an error if the flag has not been set. This means that none of the MAX6675 library methods should ever call WiringPi functions without the appropriate initialisation having taken place and succeeded beforehand. My code for this example is here. A more general solution might be to add this flag to the WiringPi library itself.

LED Display (MLMC) and Temperature Combined Example

Following my success with the temperature sensor I decided to push the boat out a little further and try to interface to my MLMC LED display system.

The MLMC LED display is a set of LED dot matrix control PCBs I designed to use up some unusual LED modules I had lying about. You can get the full story in this blog post or on the website.

Photo:  Using the WiringPi library to control an LED display and Thermocouple interface

Photo 2: Using the WiringPi library to control an LED display and thermocouple interface

This was a simple demonstration with the RasPi reading from the thermocouple interface and then displaying the temperature on the display. For this example I wrote everything in C. The MLMC interface is very simple and involves clocking 16 bit words of data using two pins, one for data and one for clock. Each word represents a single column on the LED display. This low speed (~5Kbps) synchronous protocol was originally implemented by directly manipulating the digital I/O pins on the Arduino and so was very simple to port to the RasPi with the WiringPi library.

While the ported program functions very well, the waveforms obtained from the RasPi are quite different to those achieved with the Arduino. This is a good example of how the same simple code can be quite different when ported between platforms.

MLMC Clock Waveforms

The function used to send serial data to the MLMC is shown below. This code has a 75µs delay between switching the level of the clock and this gave uniform pulses on both systems. The pulses also appeared consistent from one run to another.

Listing 2: MLMC serial data sending routine


const int spidelay_us =75;

void Send_byte( char data ///< 8 bit data to be sent
			   ) {
    uint8_t temp;	// local copy of the data to be shifted out
    uint8_t i;					
	
    temp = data;	
    for (i=0; i<8; i++) {
		// start the cycle with the clock pin low
        digitalWrite(clockPin, LOW);

		// clock out a single byte
        if (temp & (1<<7)) {
            digitalWrite(dataPin, HIGH);
        } else {
            digitalWrite(dataPin, LOW);
        }
        
		// wait for data bit to be set up
		delayMicroseconds(spidelay_us);
        
		// clock the data out by producing a rising edge
        digitalWrite(clockPin,HIGH); 
		
		// wait for mlmc to read the data bit in 
        delayMicroseconds(spidelay_us);
		
        // shift data along by one
        temp <<= 1;
    }
	
	// leave both pins low when idle 
    digitalWrite(clockPin, LOW);
    digitalWrite(dataPin, LOW);
}

The following scope traces are the result of executing Listing 2 on the Arduino:

Clock pulses from the Arduino to the MLMC modules

Figure 1: Clock pulses from the Arduino to the MLMC modules

Single clock pulse from the Arduino to the MLMC modules

Figure 2: Single clock pulse from the Arduino to the MLMC modules

Arduino has a total pulse time of approximately 80µs for the first clock pulse to MLMC. This extra 5µs I assign to the time taken to call the digitalWrite function, a single shift operation and iterating the for-loop.

The next two traces in figure 3 and figure 4 are produced when running the same code on the RasPi:

Clock pulses from the Raspberry Pi to the MLMC modules

Figure 3: Clock pulses from the Raspberry Pi to the MLMC modules

Single clock pulse from the Raspberry Pi to the MLMC modules

Figure 4: Single clock pulse from the Raspberry Pi to the MLMC modules

You can notice that while the pulses look identical at a quick glance the RasPi has 150µs pulse width; almost double that of the Arduino. I assume that the delayMicroseconds function, which only guarantees that a minimum of the given microseconds have elapsed before returning, is releasing control to the operating system and coming back a lot later than expected. As the delay implementation in the WiringPi library simply calls nanosleep I am surprised this operation takes twice as long. There may be a number of causes for this behaviour:

  • There might be a bug in the way the delay function is implemented.
  • The shift and for-loop iteration might have compiled in a very inefficient way.
  • The operating system simply cannot schedule other tasks quickly enough to return from nanosleep and meet our expectations.

MAX6675 thermocouple interface

This loop was clocking data in from the MAX6675 chip via a “bit-banged” interface. The main loop did not have a delay and was toggling bits as quickly as possible while shifting in the value via a single GPIO pin.

Listing 3: SPI send section from the MAX6675 library


digitalWrite(_CS_pin,LOW); // Enable device

/* Cycle the clock for dummy bit 15 */
digitalWrite(_SCK_pin,HIGH);
digitalWrite(_SCK_pin,LOW);

/* Read bits 14-3 from MAX6675 for the Temp 
 Loop for each bit reading the value and 
 storing the final value in 'temp' 
 */
for (int bit=11; bit>=0; bit--){
	digitalWrite(_SCK_pin,HIGH);  // Set Clock to HIGH
	value += digitalRead(_SO_pin) << bit;  // Read data and add it to our variable
	digitalWrite(_SCK_pin,LOW);  // Set Clock to LOW
}

/* Read the TC Input inp to check for TC Errors */
digitalWrite(_SCK_pin,HIGH); // Set Clock to HIGH
error_tc = digitalRead(_SO_pin); // Read data

digitalWrite(_SCK_pin,LOW);  // Set Clock to LOW
digitalWrite(_CS_pin, HIGH); // Disable Device

The following traces in figure 5 and figure 6 show the results on the Arduino.

Clock pulses from the Arduino to the MAX6675 modules

Figure 5: Clock pulses from the Arduino to the MAX6675

Single clock pulse from the Arduino to the MAX6675 modules

Figure 6: Single clock pulse from the Arduino to the MAX6675

On the Arduino this code gave a uniform pulse train with the pulse widths measuring approximately 6-7µs. As the Arduino is running at 16Mhz I would like to think this could be optimised a lot more to get something like 120ns if I used some assembly or bypassed the Wiring/Arduino API, but that is an exercise for another blog post. 🙂

Clock pulses from the Raspberry Pi to the MAX6675 modules

Figure 7: Clock pulses from the Raspberry Pi to the MAX6675

Close-up clock pulses from the Raspberry Pi to the MAX6675 modules

Figure 8: Close-up clock pulses from the Raspberry Pi to the MAX6675

The RasPi on the other hand gave a very non-uniform pulse train. As this is synchronous communication, the clock does not need to be uniform, it dictates when the data line is read. The average pulse in this waveform is only 150ns wide which is approximately 48 times faster than the Arduino. Given that the RasPi clock speed of 700MHz is roughly 44 times faster then the Arduino clock speed of 16MHz, this makes sense.

The RasPi would vary any individual pulse length by up to a factor of two (from observation) but did not seem to be effected by increasing the load (multiple ssh sessions and running an openssl speed test). The RasPi would also continue to run the MLMC scrolling display and reading the temperature sensor without issues while another process was also reading the temperature sensor at the same time (single_temp.cpp from first example above). Even while openssl was doing speed testing (cpu usage at 98-99%) the visible operation of the screen was not effected.

Investigating Further

The long delay and changing pulse widths could be investigated further with a couple of short programs.

I could investigate the long delay further by looking at repeating the test with the system under different loads and noting the effect on the width and consistency of the pulses. To vary the workload on the RasPi I could use a tool like stress.

We could also step through many values while keeping the system load constant. This would give us an idea if their was a minimum overhead experienced by the delay function or if their was some sort of error in the calibration.

I will leave these as an exercise for another day as plenty of work has already been done on this sort thing before, although not specifically on the RasPi.

Conclusions

This was a very quick look into porting code from Arduino to Raspberry Pi. I found that it was not so difficult to port some very simple applications, the majority of the code would simply run unchanged.

While the code may compile and run, the actual operation of the code will always need to be checked carefully for timing issues and other unexpected behaviour when switching hardware and using new library implementations.

As these systems were using synchronous serial communication the exact shape of the waveforms did not actually need to be uniform for the system to work.

On review of the MAX6675 data sheet the timings slighty exceed the stated maximum clock freq of 4.3Mhz. So If I was intending to use this further I would introduce a short delay into the MAX6675 clock routine to ensure it complies with the data sheet.

The MLMC module operates perfectly with the timings achieved but we are operating at half the throughput we expected due to the delay function not operating identically to the same function on the Arduino. While this didn’t cause a problem in this simple test it could easily have done so in a slightly more complicated system.

Modular LED Matrix Controller version 1.0

Monday, March 12th, 2012
 An Arduino driving 5 MLMC modules displaying the current temperature

An Arduino driving five MLMC modules displaying the current temperature

I have finally motivated myself to publish my firmware and PCB designs for the MLMC on github. The design is functional and I have a set of five modules chained together sitting on my workbench. They happily display the current temperature via an Arduino and the MAX6675 based Thermocouple board I designed previously.

All the files for the project are currently published on github at https://github.com/brokentoaster/MLMC.

Bottom view of the controller PCBs.

Bottom view of the controller PCBs.

This Modular LED Matrix Controller (MLMC) all started about 3 years ago and you can find all the info and a demonstration video at the project web page.

Once a couple of initial glitches in the system had been worked out the modules turned out to be both reliable and easy to drive.

The power consumption as on average 12mA per module while displaying scrolling text. The current consumption is reasonably nicely distributed about the average without any large peaks in current. Each module’s refresh rate is slightly out of sync with its neighbour due to the differences in each of the AVRs on-board oscillators. This has the side effect that all columns switch on at a slightly time and avoids causing a large spike in the current. While not deliberately designed to act this way it is a benefit of the multiple controller modular design.

Trying to drive 1280 LEDs from just 4 wires was not without its problems, the three main problems are covered in greater detail in later posts but in brief they were as follows:

  • Synchronisation issues caused by jitter, noise and missing bits
  • Clocking out the last word from one module to the next
  • PCB design error – SPI pins are not always the same as the ISP serial programming pins.
  • Component Choice. Not enough memory for desired bit depth or bandwidth to achieve original functionality
  • USI in SPI mode is not the same as hardware SPI

Arduino MP3

Tuesday, July 5th, 2011

ArduinoMP3 (Rev C)

The Arduino MP3 webpage is finally up and the source code for the project is on github.

You can find the web pages at:

http://www.brokentoaster.com/arduinomp3

You can find all the future development at GitHub via this link:

https://github.com/brokentoaster/ArduinoMP3

Using thermocouples with the Reprap Mendel

Monday, September 6th, 2010

Using thermocouples with the Reprap Mendel is pretty straight forward, although I did overcome a couple of issues in getting it working.

A known issue with the MAX6675 Arduino/Reprap code

The MAX6675 chip can take up to 220ms to take a reading from the thermocouple and the reading begins automatically after the previous read. If another read is attempted before the current reading has been completed then the chip returns the previous value and restartsthe internal analog to digital the conversion. This means that if you read from the chip every 150ms or so you will always get the same first reading returned again and again.

The arduino library code needs a 220ms delay between multiple reads to allow for the MAX6675 chip to take another reading. In the current state the library simply reads the same value repeatedly. Luckily it is a known issue documented on the project’s site and is not hard to fix.

The taking of a single reading rather than taking a number of readings and averaging will contribute to a high noise level in the thermocouple readings when using this software.

Discovering the problem

When testing the PCB with the library code everything works fine. The arduino returns a reading every second and everything looks good.

When using the Reprap firmware with the thermocouple code it always returned the first value read from the chip (usually 24°C or so). This lead to things getting pretty hot as the extruder would turn the heater to full duty cycle while recording no change in temperature.

I first looked at the SPI lines on the scope to see if there was excessive noise or some other issue. I also compared this side by side with the ‘working’ arduino system. The scope traces are shown below. The reference channels (R1 and R2) are the reprap firmware and the bottom traces (1 and 2) are the arduino. I noticed nothing wrong with the traces, they both looked very good.

Reprap code compared to aduino library code communicating to the MAX6675.

It was here however that I noticed that the arduino code calls another read to the chip immediately after the preceding read. After a bit more investigation I noticed that the library software calls the temperature reading function 5 times consecutively and always returns 5 identical results. A quick read of the data sheet confirmed the typical conversion time to be 170ms with a maximum of 220ms. The arduino library starts a conversion just 20μs after finishing reading the last. Reading the data sheet further also confirmed the action of restarting a conversion every time the chip is read.

I monitored the lines on a scope and found that the Reprap software was indeed reading the chip every 136ms. To fix this I simply changed SLOW_CLOCK in configuration.h to 8089 from 5000. Based on the current delay giving 136ms, this gives 220ms delay between calls to the thermocouple chip. After making this change to the firmware the thermocouple now works perfectly.

Time between calls to the MAX6675 thermocouple chip using the standard firmware on my reprap.

Fixing the problem

A more robust fix to the reprap extruder firmware is shown below, but I have not tested this code yet. This simply exits the temperature reading method if enough time has not elapsed between calls to the function. The advantage of this is that the main loop can run as fast as it needs to without impacting on the operation of the thermocouple sensors.

#ifdef MAX6675_THERMOCOUPLE
#define MAX6675_CONVERSION_TIME 220 // number of milliseconds between valid temperature readings

  int value = 0;
  byte error_tc;
  
  static unsigned long last_read_time=0; // number of milliseconds since power on at last MAX6675 read 
  unsigned long time_since_last_read=0;  // number of milliseconds since last read of MAX6675 

  /* check the chip is ready to produce a new sample */
  time_since_last_read=millis()-last_read_time;

  /* only read from the chip if a conversion has been completed */
  if(time_since_last_read > MAX6675_CONVERSION_TIME){
    
    digitalWrite(TC_0, 0); // Enable device
  
    /* Cycle the clock for dummy bit 15 */
    digitalWrite(SCK,1);
    digitalWrite(SCK,0);
  
    /* Read bits 14-3 from MAX6675 for the Temp
     	 Loop for each bit reading the value 
     */
    for (int i=11; i>=0; i--)
    {
      digitalWrite(SCK,1);  // Set Clock to HIGH
      value += digitalRead(SO) << i;  // Read data and add it to our variable
      digitalWrite(SCK,0);  // Set Clock to LOW
    }
  
    /* Read the TC Input inp to check for TC Errors */
    digitalWrite(SCK,1); // Set Clock to HIGH
    error_tc = digitalRead(SO); // Read data
    digitalWrite(SCK,0);  // Set Clock to LOW
  
    digitalWrite(TC_0, 1); //Disable Device
  
    last_read_time = millis(); //remember the read time for next time
  
    if(error_tc)
      currentTemperature = 2000;
    else
      currentTemperature = value>>2;
  }
#endif

}

The arduino library can be improved by simply inserting the following at line 55 of the file MAX6675.cpp just before the end of the for loop.

if (i>1) delay(220); // Wait 220ms for next sample to be ready

This will force a 220ms delay when reading the thermocouple multiple times via the read_temp(int samples) function. Alternatively you could use the millis() function to track the last time it was read and automatically delay the read by the appropriate amount.

Arduino MP3 Shield Rev B (correct files this time)

Monday, June 14th, 2010

I have to apologise to everyone who downloaded the Revision B Arduino MP3 Shield PCBs when I posted them here and here.

I accidently uploaded and emailed everyone the wrong files, not only were they not revision B they weren’t even revision A. This was totally my fault as I grabbed the files from the wrong directory when uploading. I was sure I had checked they were correct but obviously I hadn’t.

I’ve included some pictures of what the layout is supposed to look like for Rev B so you can check the gerbers and EAGLE files are correct before getting any made. ( Look for the large ‘B’ on the top copper layer.)




Figure 1 : Arduino MP3 Shield Rev B PCB - Top view




Figure 2 : Arduino MP3 Shield Rev B PCB - Bottom view

I have since fixed the links and are now hosting the correct files. Here are the links again:

EAGLE files are here

GERBER files are here

Arduino Library files are here

PDF of the schematic is here

Once again sorry to everyone who got the wrong files.

Creative Commons License
Arduino MP3 Shield by Nick Lott is licensed under a Creative Commons Attribution-Share Alike 2.0 UK: England & Wales License.
Based on a work at www.brokentoaster.com.

Arduino MP3 Rev B v0.0

Monday, February 15th, 2010

Last week I managed to have some luck with my Arduino MP3 shield. The big hold up was caused by not having enough power from the FT232RL chip to supply the decoder and the memory card at the same time (50mA max d-oh). I also had a software issue, I had not altered the code to deal with the 16Mhz clock speed of the arduino from the 8Mhz I was using on the ButterflyMP3 project. The SPI clock was running at 8Mhz where it needed to be slower than 6MHz (to comply with the VS1011E datasheet). Once I had that sorted everything just popped into place and started working reliably.

I apologise in advance for the poor integration of the library examples. I have simply and quite roughly ported the minimal parts of my buterflymp3 project over to the arduino and this hardware. The examples will test reading FAT16 file system on the MMC/SD card, test the VS1011E decoder chip, and play the first mp3 file found on the memory card. I hope to get these tidied up later but have not had any time to do so lately.

The PCB has not actually been tested yet so I’d hold off building a million of these until after a successful test. There is unlikely to be much wrong with it though as I have simply added a voltage regulator and re routed a couple of signals to fix my earlier mistakes. ( I’d forgotten that I/O lines 0 and 1 are used by the uart on the arduino)

I have embedded the BOM below. ( The bom is here if you don’t see it below)

Here are all the files so far. These are all released under a Creative Commons 2.5 license .

EAGLE files are here

GERBER files are here

Arduino Library files are here

PDF of the schematic is here

To use the library simply put the “mp3” folder from the zip file inside the “libraries” folder in your arduino folder (create one if it doesn’t exist). Restart Arduino 018 or later and you should have “mp3” entries in the menus under examples and import libraries.

The BOM references a 2.8V LDO voltage regulator but the schematic shows a 3.3V. Either will work fine but the 2.8 will give you slightly lower power usage.

If you are interested in PCBs or kits, drop me a line at buy_pcbs@brokentoaster.com
As always any comments, suggestions or ideas are welcome.

New PCBs in from BatchPCB

Tuesday, January 5th, 2010


My order of PCBs from BatchPCB arrived the week before Christmas so plenty of soldering and things to keep me busy over the holiday. I’ve also been distracted of late with building a reprap, although I’ve not got much further than amassing a number of PCBs, components and motors, watch this space for details as the build progresses.

My Batch PCB contained a new version of the Arduino MP3 board with provision for running from the 5V Duemilanove Arduino and a number of MLMC boards so I can string them together for testing. Unfortunately the ArduinoMP3 PCB had a couple of design errors, which is typical when your working on a design off and on over a course of months. The design will probably be released soon, but the libraries and demo code are also proving slightly more difficult.

Some changes to Hardware.
The basic design of the board is the same, VS1011 and SD card shared on the SPI bus with a 5 way Joystick on some digital lines.

I forgot about the TX/RX lines being shared with digital 0 and 1 on the arduino so I’ve had to re-route signals using those pins to the previously unused analog/general IO pins.

A couple of changes related to running the circuits on a 5V / 3V3 system. My Butterfly MP3 system that I based this on was powered from a single supply rail of 2.8V. The FTDI USB chip on the arduino was originally used to provide a 3V3 supply to the shield. I thought the 50 mA stated in the data sheet would be enough as my butterfly mp3 system only used about 50mA including processor and display. Unfortunately the is a large current draw when an SD Card is inserted causing the FTDI chip to reset and breaking connection with the PC. Although not a big problem I decided to add an LP2981 LDO regulator to supply a 100mA for the card and MP3 player circuits. If you don’t want to use this then you can not fit the parts and easily bypass with a jumper wire.

C++ing the libraries
I was hoping to use the existing libraries for the Arduino and SD cards to access the MMC/SD Cards and provide demo code to show using the shield. For an as yet unknown reason the existing libraries from Adafruit wave shield do not work. In order to test my hardware I have converted my MMC and FAT libraries from the ButterflyMP3 project to C++ for use with the Arduino system. I few teething problems and issues as I remember how C++ works and I now have a working SD Card system. Output from my current software is shown below

I’d like to use the already available libraries as they offer FAT32 and extended features over my bare bones implementation – so not quite ready to publish any finished code just yet.

Next step is adding the support for the VS1011. Again not quite as smooth as I’d hopped but moving along with the help of the old intronix logic port. Currently the VS1011 is not setting up correctly. Occasionally it plays OK but mostly nothing or a very slow version of a song, indicating to me the clock registers are not being set correctly.

I think another weekend or so of work and I’ll be there but if you’d like a copy of the current PCBs or Arduino files then just drop me an email or leave a comment.

Current Demo Software Terminal Output

TEST
0
MMC_RESET returned 0
MMC_SEND_STATUS returned 0
MMC_SEND_CID returned 0
0: FE 02 54 4D 53 44 30 31 47 28 9A CF 7B 33 00 7A ..TMSD01G(...3.z
1: 83 08 8E FF FF FF FF FF FF FF FF FF FF FF FF FF ................
MMC_SEND_CSD returned 0
0: FE 00 2D 00 32 5B 59 83 D6 7E FB FF 80 16 40 00 ..-.2[Y.......@.
1: FB 5E C9 FF FF FF FF FF FF FF FF FF FF FF FF FF .^..............
MMC_Capacity returned 1037952
MMC_Name returned 0 SD01G(
MMC_Read returned 0
MMC First Sector:
0: FA 33 C0 8E D0 BC 00 7C 8B F4 50 07 50 1F FB FC .3........P.P...
1: BF 00 06 B9 00 01 F2 A5 EA 1D 06 00 00 BE BE 07 ................
2: B3 04 80 3C 80 74 0E 80 3C 00 75 1C 83 C6 10 FE ...<.t..<.u.....
3: CB 75 EF CD 18 8B 14 8B 4C 02 8B EE 83 C6 10 FE .u......L.......
4: CB 74 1A 80 3C 00 74 F4 BE 8B 06 AC 3C 00 74 0B .t..<.t.....<.t.
5: 56 BB 07 00 B4 0E CD 10 5E EB F0 EB FE BF 05 00 V.......^.......
6: BB 00 7C B8 01 02 57 CD 13 5F 73 0C 33 C0 CD 13 ......W.._s.3...
7: 4F 75 ED BE A3 06 EB D3 BE C2 06 BF FE 7D 81 3D Ou.............=
8: 55 AA 75 C7 8B F5 EA 00 7C 00 00 49 6E 76 61 6C U.u........Inval
9: 69 64 20 70 61 72 74 69 74 69 6F 6E 20 74 61 62 id partition tab
A: 6C 65 00 45 72 72 6F 72 20 6C 6F 61 64 69 6E 67 le.Error loading
B: 20 6F 70 65 72 61 74 69 6E 67 20 73 79 73 74 65  operating syste
C: 6D 00 4D 69 73 73 69 6E 67 20 6F 70 65 72 61 74 m.Missing operat
D: 69 6E 67 20 73 79 73 74 65 6D 00 00 00 00 00 00 ing system......
E: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
F: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
11: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
12: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
13: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
14: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
15: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
16: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
17: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
19: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1A: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1B: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 ................
1C: 37 00 06 03 C3 E6 F3 00 00 00 0D B3 1E 00 00 00 7...............
1D: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1E: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
1F: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA ..............U.
0
SECTORS PER CLUSTOR 20
BYTES PERSECTOR 0200
FAT Init returned:0
SECTORS PER CLUSTOR 20
BYTES PERSECTOR 0200
FAT boot Sector info
FAT begins at sector 244
Clusters begin at sector 768
Sectors per cluster = 32
Root dir starts at sector 736
THESTR~1.MP3 00045 037A00 2E0F
THESTR~2.MP3 00124 03400 2E1A
THESTR~3.MP3 001F5 025C00 2E24
THESTR~4.MP3 0028C 030400 2E2E
TWINSE~1.MP3 0034D 051B249 2E39
THEWHI~1.MP3 00494 03867AF 2E45
THESTR~5.MP3 0057B 02FE00 2E51
THESTR~6.MP3 0063B 032B00 2E5C
THESTR~7.MP3 0079 034D00 2E68
BEASTI~1.MP3 007DD 02EC9A4 2E74
BEASTI~2.MP3 00899 02E93C3 2E80
BEASTI~3.MP3 00954 01F172F 2E8B
THESTR~8.MP3 009D1 03A300 2E95
THESTR~9.MP3 00ABA 02DC00 2E9F
THEST~10.MP3 00B71 02F00 2EA9
THEST~11.MP3 00C2D 026900 2EB4
05-ILE~1.MP3 00CC8 02E8C16 2EBD
BEASTI~4.MP3 00D83 03EF2C9 2EC8
Files: 18
1A
DONE