Hitachi 63B09E SBC

I recently learned that there is some kind of a new thing started up that is all about Motorola? CPU based single board computers. So I thought I’d post one that I made in uni about 28 years ago. The label on the EPROM is Assist09 so it’s possible that it would boot and allow me to upload code etc if I had a serial cable of the right kind. The board was part of an ultrasonic range finder project I made for uni. I made 3 main boards (all hand wired) along with a sonar head which had yet another board with OpAmps. There was also a power supply box, a keyboard and an LCD. – these days you could do the same thing with an Ardunino Pro Mini, an I2C display and an ebay ultrasound module. The software had a menu system I copied from Supercalc. I wrote most of the software in ‘C’, to do this I found some code to give an early version of GCC the ability to generate 6809 assembler. This ‘OS’ had only the keyboard scanning and interrupt code in assembler. I remember running pmake on the unix server at RMIT when I was compiling the compiler and almost bringing the server to its knees.

The Hitachi 6309 was an enhanced version of the Motorola 6809 Hitachi 6309, and I think I did use some of the extra instructions. I believe there was a 16 to 32 bit multiplication available which I used.

As you can see this was point to point soldered; at that time I had no practical / cost effective way of making a PCB. I am tempted now to do something with this computer, at least to see if it still works, although I have thrown my EPROM programmer and any capability to erase EPROM’s into the tip. I’m sure there are ebay cables, programmers and erasers.. Of course If I can find the actual EPROM with the sonar software, surely I haven’t thrown that away.

Perhaps this is of interest to someone.

Cpu Detail

Cpu Detail

Front of board.

Front of board.

Back of board.

Back of board.

Debugging the DYPTH01B-SPI

This is a description of the methods I used to get a DYPTH01B-SPI temperature and humidity sensor working with my Arduino Pro Mini. I’d almost given up on the thing many times; it has been a struggle to get any meaningful data out of the device. In the end I discovered what I think is a weird interaction between the example code I had copied and the compiler. This was a red herring that caused me to look down incorrect paths whilst I was debugging.

When I purchased the device I didn’t have a clear idea of what I would use the sensor for; I just liked the idea of measuring some real world data. My intent now is to use a couple of nRF radio transceivers to remotely sample data with the sensor being mounted outside.

I’d had the DYPTH for a while, but hadn’t done anything with it. This neglect was due to a lack of confidence in my ability to get it working, and because I had gotten distracted discovering that cheap ebay robotics motors aren’t precision devices…  (You’ve probably seen the little yellow DC motors on ebay.)

The DYPTH01B is weird because it acts mostly as a master but the slave must tell it to send. The DYPTH01B generates the clock and uses MOSI but the CE must be controlled by the slave which in my case is an Arduino Pro Mini.

I initially tried to use the code I found from here (see the section on Sensor 2).  I managed to get the same poor result that Matthew Little did which is that every now and then valid data appears (although the humidity seems a little high).  Some of the data seems almost random and has an invalid CRC and so is not converted to temperature and humidity. Sometimes a valid CRC is calculated from bad data so then I got weird temperature and humidity values including -ve values.

The following list I shows a selection of this bad data. The lists shows the 4 bytes received from the SPI and then the temperature and humidity calculated from these bytes in the cases where the CRC is correct:

0,81
1,2E
2,20
3,E9

0,1
1,2D 
2,A0
3,BE
T=-9.-9C, H=160%

0,28
1,34
2,80
3,4B

0,1
1,2D
2,A0
3,BE
T=-9.-9C, H=160%0,41

The following is my modified code that produces the above result:

// Written by Nick Gammon
// February 2011
// see http://mushclient.com/spi

// Rework for DYPTH01B_SPI Temperature and Humidity sensor
// using MTH01 Sensor
// D. Richards, Jan 2012
// see http://www.suntekstore.co.uk/product-14001923-DYPTH01B-SPI+Temperature++Humidity+Sensor+Module.html


int ledToggle = -1;
int ledCounter = 0;

#include <LiquidCrystal.h>
/* YourDuino.com Example Software Sketch
 16 character 2 line I2C Display
 Backpack Interface labelled "YwRobot Arduino LCM1602 IIC V1"
 terry@yourduino.com */

/*-----( Import needed libraries )-----*/
#include <Wire.h>  // Comes with Arduino IDE
// Get the LCD I2C Library here:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
// Move any other LCD libraries to another folder or delete them
// See Library "Docs" folder for possible commands etc.
#include <LiquidCrystal_I2C.h>

/*-----( Declare Constants )-----*/
/*-----( Declare objects )-----*/
// set the LCD address to 0x27 for a 20 chars 4 line display
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address



//Arduino Pin =>  DYPTH01 Function
// SS         =>  LOW
// 11 MOSI    =>  SDAT
// 12 MISO    =>  nc
// 13 CLK     =>  SCK

// 5V         =>  VDD
// GND        =>  VSS
// 7          =>  Reset
// 8          =>  CE

//#include "pins_arduino.h"

byte buf[40];
volatile byte pos;
volatile boolean process_it;
int MTH_temperature;
int MTH_humidity;
#define HCS 8
#define HRT 7
#define FRQ_MON 5
byte clr;

/*
  The following procedure calculates the CRC-8. The result accumulates in the variable CRC.
  Var CRC : Byte;
  Procedure calc_CRC(X: Byte);

  Begin
  CRC := CRC_Table[X xor CRC];
  End;

 Polynomial is x^8 + x^5 + x^4
*/

const unsigned char CRC8table[256] PROGMEM = {

  0, 49, 98, 83, 196, 245, 166, 151, 185, 136, 219, 234, 125, 76, 31, 46,
  67, 114, 33, 16, 135, 182, 229, 212, 250, 203, 152, 169, 62, 15, 92, 109,
  134, 183, 228, 213, 66, 115, 32, 17, 63, 14, 93, 108, 251, 202, 153, 168,
  197, 244, 167, 150, 1, 48, 99, 82, 124, 77, 30, 47, 184, 137, 218, 235,
  61, 12, 95, 110, 249, 200, 155, 170, 132, 181, 230, 215, 64, 113, 34, 19,
  126, 79, 28, 45, 186, 139, 216, 233, 199, 246, 165, 148, 3, 50, 97, 80,
  187, 138, 217, 232, 127, 78, 29, 44, 2, 51, 96, 81, 198, 247, 164, 149,
  248, 201, 154, 171, 60, 13, 94, 111, 65, 112, 35, 18, 133, 180, 231, 214,
  122, 75, 24, 41, 190, 143, 220, 237, 195, 242, 161, 144, 7, 54, 101, 84,
  57, 8, 91, 106, 253, 204, 159, 174, 128, 177, 226, 211, 68, 117, 38, 23,
  252, 205, 158, 175, 56, 9, 90, 107, 69, 116, 39, 22, 129, 176, 227, 210,
  191, 142, 221, 236, 123, 74, 25, 40, 6, 55, 100, 85, 194, 243, 160, 145,
  71, 118, 37, 20, 131, 178, 225, 208, 254, 207, 156, 173, 58, 11, 88, 105,
  4, 53, 102, 87, 192, 241, 162, 147, 189, 140, 223, 238, 121, 72, 27, 42,
  193, 240, 163, 146, 5, 52, 103, 86, 120, 73, 26, 43, 188, 141, 222, 239,
  130, 179, 224, 209, 70, 119, 36, 21, 59, 10, 89, 104, 255, 206, 157, 172,
};


void setup (void)
{

   pinMode(HCS, OUTPUT);        // CS output
  digitalWrite(HCS, HIGH);     // CS inactive
  pinMode(HRT, OUTPUT);        // RST output
  digitalWrite(HRT, LOW);     // RST active
  delay(2);
  digitalWrite(HRT, HIGH);     // RST inactive

#ifdef LCD
  lcd.begin(16, 2);  // initialize the lcd for 16 chars 2 lines, turn on backlight
  lcd.backlight(); // finish with backlight on

  //-------- Write characters on the display ------------------
  // NOTE: Cursor Position: (CHAR, LINE) start at 0
  lcd.setCursor(0, 0); //Start at character 4 on line 0
  lcd.print("Weather");
#else
  Serial.begin (115200);   // debugging
  Serial.println ("initialising");
#endif
  

 

  delay(1000); // 100ms delay after reset.

  // get ready for an interrupt
  pos = 0;   // buffer empty
  process_it = false;

  //Sample on falling edge
  SPCR |= _BV(CPHA);

  // Clock idle when low set CPOL to 0
  SPCR &= ~_BV(CPOL);


  //  Slave mode
  SPCR &= ~_BV(MSTR);

  // Enables  SPE = 1
  SPCR |= _BV(SPE);

  clr = SPSR;
  clr = SPDR;
  // now turn on interrupts
  SPCR |= _BV(SPIE);



  digitalWrite(HCS, LOW);      // CS active, starts conversion

}  // end of setup


// SPI interrupt routine
ISR (SPI_STC_vect)
{
  byte c = SPDR;  // grab byte from SPI Data Register

  // add to buffer if room
  if (pos < 4)
  {
    buf[pos] = c;
    pos++;
    if (pos >= 4) // when all 4 bytes received
    {
      pos = 0;
      digitalWrite(HCS, HIGH);  // disable further conversions
      process_it = true;      // signal ready to main loop
    }
  }  // end of room available

}  // end of interrupt routine SPI_STC_vect

// main loop - wait for flag set in interrupt routine
void loop (void)
{
  byte idx;
  byte crc;
  byte byt;
  int i;

  


  if (process_it)
  {
    crc = 0;
    for (i = 0; i < 4; i++)
    {
      byt = buf[i];
      idx  =  byt ^ crc;
      //      idx  =  buf[i] ^ crc;
      crc = CRC8table[idx];
      //      crc = CRC8table[buf[i] ^ crc];
#ifndef LCD
/*
      Serial.print(" n");
      Serial.print(i, HEX);
      Serial.print(" b");
      Serial.print(byt, HEX);
      Serial.print(" c");
      Serial.print(crc, HEX);
      Serial.print(" i");
      Serial.print(idx, HEX);
      Serial.println(">");
*/
#endif
    }
#ifndef LCD
   for (i = 0; i < 4; i++)
   {
     Serial.print(i);
     Serial.print(",");
     Serial.print(buf[i], HEX);
     Serial.println();
   }
#endif
    
    

#ifndef LCD
    //Serial.print(crc, HEX);
    //Serial.print(", ");
    //Serial.println(buf[3], HEX);
#endif

    if (crc == 0 && ((buf[0] & 0xf0) == 0))
    {
      MTH_temperature = ( (256 * buf[0]) + buf[1] ) - 400;
      MTH_humidity = buf[2];
#ifdef LCD
      lcd.setCursor(0, 0); //Start at character 4 on line 0
      lcd.print("T=");
      lcd.print( MTH_temperature / 10);
      lcd.print(".");
      lcd.print( MTH_temperature % 10);
      lcd.print("C");
      lcd.setCursor(0, 1); //Start at character 4 on line 0
      lcd.print("H=");
      lcd.print(MTH_humidity);
      lcd.print("%");
#else

      Serial.print(" T=");
      Serial.print( MTH_temperature / 10);
      Serial.print(".");
      Serial.print( MTH_temperature % 10);

      Serial.print("C, H=");
      Serial.print(MTH_humidity);
      Serial.print("%");

#endif
    }
    else
    {
      // reset chip here
      digitalWrite(HRT, LOW);     // RST active
      delay(2);
      digitalWrite(HRT, HIGH);     // RST inactive
#ifndef LCD
      Serial.print("Reset");
#endif
      delay(100);
    }
    //   Serial.println();

    delay(2000);
  //  pos = 0;                // reset buffer index
    process_it = false;     // preset buffer not ready
    clr = SPSR;
    clr = SPDR;
    digitalWrite(HCS, LOW);    // start conversion

  }  // end of flag set

}  // end of loop

In particular note that I believe the setup of the SPI had some problems (although it’s possible that the SPI defaults to my explicit settings) eg -ve edge clock and clock idle low.

I fiddled around with this a while but almost gave up because there seemed to be too many variables – I didn’t know what was working.  Then the idea came that I should be able to bypass the SPI and read the CLK and MOSI data directly by turning the Arduino into a slow logic analyzer.  I determined that I could make a loop that could execute at about 25khz that was able to read two pins and store the data in an array. My vague understanding of nyquist indicates that this should enable me to sample a clock not more then 1/3 of this frequency which is higher than the 3khz DYPTH clock.  So the following code reads the temperature and humidity by interpreting the binary data from the pins of the DYPTH.

// Written by Nick Gammon
// February 2011
// see http://mushclient.com/spi

// Rework for DYPTH01B_SPI Temperature and Humidity sensor
// using MTH01 Sensor
// D. Richards, Jan 2012
// see http://www.suntekstore.co.uk/product-14001923-DYPTH01B-SPI+Temperature++Humidity+Sensor+Module.html


int ledToggle = -1;
int ledCounter = 0;

#include <LiquidCrystal.h>
/* YourDuino.com Example Software Sketch
 16 character 2 line I2C Display
 Backpack Interface labelled "YwRobot Arduino LCM1602 IIC V1"
 terry@yourduino.com */

/*-----( Import needed libraries )-----*/
#include <Wire.h>  // Comes with Arduino IDE
// Get the LCD I2C Library here:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
// Move any other LCD libraries to another folder or delete them
// See Library "Docs" folder for possible commands etc.
#include <LiquidCrystal_I2C.h>

/*-----( Declare Constants )-----*/
/*-----( Declare objects )-----*/
// set the LCD address to 0x27 for a 20 chars 4 line display
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

//Arduino Pin =>  DYPTH01 Function
// SS         =>  LOW
// 11 MOSI    =>  SDAT
// 12 MISO    =>  nc
// 13 CLK     =>  SCK

// 5V         =>  VDD
// GND        =>  VSS
// 7          =>  Reset
// 8          =>  CE

//#include "pins_arduino.h"

byte buf[40];
volatile byte pos;
volatile boolean process_it;
int MTH_temperature;
int MTH_humidity;
#define HCS 8
#define HRT 7
#define FRQ_MON 5
byte clr;

/*
  The following procedure calculates the CRC-8. The result accumulates in the variable CRC.
  Var CRC : Byte;
  Procedure calc_CRC(X: Byte);

  Begin
  CRC := CRC_Table[X xor CRC];
  End;

 Polynomial is x^8 + x^5 + x^4
*/

const unsigned char CRC8table[256] PROGMEM = {

  0, 49, 98, 83, 196, 245, 166, 151, 185, 136, 219, 234, 125, 76, 31, 46,
  67, 114, 33, 16, 135, 182, 229, 212, 250, 203, 152, 169, 62, 15, 92, 109,
  134, 183, 228, 213, 66, 115, 32, 17, 63, 14, 93, 108, 251, 202, 153, 168,
  197, 244, 167, 150, 1, 48, 99, 82, 124, 77, 30, 47, 184, 137, 218, 235,
  61, 12, 95, 110, 249, 200, 155, 170, 132, 181, 230, 215, 64, 113, 34, 19,
  126, 79, 28, 45, 186, 139, 216, 233, 199, 246, 165, 148, 3, 50, 97, 80,
  187, 138, 217, 232, 127, 78, 29, 44, 2, 51, 96, 81, 198, 247, 164, 149,
  248, 201, 154, 171, 60, 13, 94, 111, 65, 112, 35, 18, 133, 180, 231, 214,
  122, 75, 24, 41, 190, 143, 220, 237, 195, 242, 161, 144, 7, 54, 101, 84,
  57, 8, 91, 106, 253, 204, 159, 174, 128, 177, 226, 211, 68, 117, 38, 23,
  252, 205, 158, 175, 56, 9, 90, 107, 69, 116, 39, 22, 129, 176, 227, 210,
  191, 142, 221, 236, 123, 74, 25, 40, 6, 55, 100, 85, 194, 243, 160, 145,
  71, 118, 37, 20, 131, 178, 225, 208, 254, 207, 156, 173, 58, 11, 88, 105,
  4, 53, 102, 87, 192, 241, 162, 147, 189, 140, 223, 238, 121, 72, 27, 42,
  193, 240, 163, 146, 5, 52, 103, 86, 120, 73, 26, 43, 188, 141, 222, 239,
  130, 179, 224, 209, 70, 119, 36, 21, 59, 10, 89, 104, 255, 206, 157, 172,
};

const int MAX_VALUES = 250;
const int TURN_OFF_POINT = 200; //266;
byte pinReading13[MAX_VALUES];
byte pinReading11[MAX_VALUES];
void setup (void)
{

  lcd.begin(16, 2);  // initialize the lcd for 16 chars 2 lines, turn on backlight
  lcd.backlight(); // finish with backlight on

  Serial.begin (115200);   // debugging
  Serial.println ("initialising");
  pinMode(11, INPUT);
  pinMode(13, INPUT);
  pinMode(HCS, OUTPUT);
  digitalWrite(HCS, HIGH);
  pinMode(FRQ_MON, OUTPUT);
  return;



}  // end of setup


// SPI interrupt routine
ISR (SPI_STC_vect)
{
  byte c = SPDR;  // grab byte from SPI Data Register

  // add to buffer if room
  if (pos < sizeof buf)
  {
    buf [pos++] = c;

    if (pos >= 4) // when all 4 bytes received
    {
      digitalWrite(HCS, HIGH);  // disable further conversions
      process_it = true;      // signal ready to main loop
    }
  }  // end of room available

}  // end of interrupt routine SPI_STC_vect

// main loop - wait for flag set in interrupt routine
void loop (void)
{
  byte idx;
  byte crc;
  byte byt;
  int i;
  while (1)
  {
    delay(1000);
    // As soon as HCS goes low we start reading 11 and 13
    digitalWrite(HCS, LOW);
    byte pin13 = 0;
    byte pin11 = 0;
    byte bitPos = 7;
    int x = 0;
    char toggle = -1;
    while (x < MAX_VALUES)
    {
      //  toggle *= -1;
      //  if (toggle == -1)
      //    digitalWrite(FRQ_MON, LOW);
      //  else
      //   digitalWrite(FRQ_MON, HIGH);
      pin13 |=  digitalRead(13) << bitPos;
      pin11 |=  digitalRead(11) << bitPos;

      if (bitPos == 0)
      {
        //  lcd.setCursor(0, 0); //Start at character 4 on line 0
        //  lcd.print(pin11);
        pinReading11[x] = pin11;
        pinReading13[x] = pin13;
        pin11 = 0;
        pin13 = 0;
        bitPos = 7;
        x++;
      }
      else
      {
        bitPos--;
      }

      if (x >= TURN_OFF_POINT)
      {
        digitalWrite(HCS, HIGH);
      }
      // digitalWrite(FRQ_MON,HIGH);

    }
    /*
      Use the digital data to find the temperature.
    */
    int byteCounterForCollectedData = 0;
    int bitCounterForCollectedData = 7;
    int lastClkBit = 0;
    int currentClkBit = 0;
    int byteCounterForConvertedData = 0;
    int bitCounterForConvertedData = 7;
    int dataBit = 0;
    byte dataByte = 0;
    byte dataBytes[4];

    while (byteCounterForCollectedData < MAX_VALUES)
    {
      currentClkBit = 0;
      if ((pinReading13[byteCounterForCollectedData] & (1 << bitCounterForCollectedData)) > 0)
        currentClkBit = 1;
      if ((lastClkBit == 1) && (currentClkBit == 0))  // We have a -ve transition in the input bit stream as sampled from the SPI clock.
      {
        dataBit = 0;
        if ((pinReading11[byteCounterForCollectedData] & 1 << bitCounterForCollectedData) > 0)
        {
          dataBit = 1;
        }

        dataByte |= dataBit << bitCounterForConvertedData;
        bitCounterForConvertedData--;
        if (bitCounterForConvertedData < 0)
        {
          dataBytes[byteCounterForConvertedData] = dataByte;
          dataByte = 0;
          bitCounterForConvertedData = 7;
          byteCounterForConvertedData++;
        }


      }
      lastClkBit = currentClkBit;
   



      bitCounterForCollectedData--;
      if (bitCounterForCollectedData < 0)
      {
        bitCounterForCollectedData = 7;
        byteCounterForCollectedData++;
      }

    }

    int temperature;
    for (int convertedByteCount = 0; convertedByteCount < 4; convertedByteCount++)
    {
      Serial.print(dataBytes[convertedByteCount], HEX);
      Serial.print(",");
     
      
    }
     temperature = (dataBytes[0] * 256 + dataBytes[1]) - 400;
     Serial.print(temperature / 10);
     Serial.print(".");
     Serial.print(temperature % 10);
     Serial.print(" C,");
      Serial.print(dataBytes[2]);
     Serial.print(" %");
     
    Serial.println("");

    /*
      for (int x = 0; x < MAX_VALUES; x++)
      {
        Serial.print(pinReading11[x], HEX);
        Serial.print(",");
        Serial.print(pinReading13[x], HEX);
        Serial.println("");
      }
      while (1)
      {
      }
    */
  }



}  // end of loop

And this seems to work perfectly and the operation of the DYPTH agrees with the specs.  Ie after the CE is made low there is a delay before the device outputs 32 bits of data and if CE is only low for a short period then no more data is sent.   So now I could be confident that at least one thing was working.

So this morning as I was writing this entry I first did a recheck of my pin connections and found that where I had thought I’d connected Arduino SS low I had instead connected MISO low meaning that SS was floating. When I connected SS low I get much more consistent data.  Below is the data, note that I pinched the sensor with my fingers so both the temperature and humidity change, is it measuring my humidity?  In any case  valid data appears from the start (although I am ignoring the CRC).

initialising
2,5C,41,D3,20.4 C,65 %
2,5C,41,D3,20.4 C,65 %
2,5C,41,D3,20.4 C,65 %
2,5E,41,A,20.6 C,65 %
2,5C,41,D3,20.4 C,65 %
2,5D,41,27,20.5 C,65 %
2,5B,41,7D,20.3 C,65 %
2,5C,41,D3,20.4 C,65 %
2,5F,42,AD,20.7 C,66 %
2,63,42,AB,21.1 C,66 %
2,66,43,ED,21.4 C,67 %
2,6B,45,B,21.9 C,69 %
2,70,45,7F,22.4 C,69 %
2,74,46,AF,22.8 C,70 %
2,76,47,47,23.0 C,71 %
2,7B,48,29,23.5 C,72 %
2,7C,49,B6,23.6 C,73 %
2,7D,4A,11,23.7 C,74 %
2,7C,4B,D4,23.6 C,75 %

 

So now I need to find out which of my code changes was the correct fix. First thing is that if I now ignore the CRC (in my modified version of the original code which uses SPI) then the values all seem good. Perhaps CRC is incorrectly generated or calculated on the Arduino side.

What I find is that there seems to be no impact between my setup of the SPI and the original so long as I ignore CRC. The only things I find is that the Arduino SS pin is not specified as connected so I assume that it wasn’t when Matthew Little did his experiments. Leaving the SS pin floating seems to introduce random data. Note that I did try leaving the DYPTH CE line low all the time and this causes no issues. Using the CRC code to do a reset causes data problems since we probably aren’t waiting long enough for the reset to occur.

What I found next during my debugging of the CRC generation was that adding extra code to be used to debug the system caused the CRC to be calculated incorrectly. For example when I added the following code I got a different sequence of CRC problems. Believe it or not. I went back and forward, adding and removing this code and always go similar results. So, something seemed very strange.

      Serial.print(" i:");
      Serial.print(i, HEX);
      Serial.print(" b:");
      Serial.print(byt, HEX);
      Serial.print(" c:");
      Serial.print(crc, HEX);  
      Serial.println(">");

To me this seemed like some form of compiler issue or memory corruption due to bad code. I had already looked at changing the datatypes used in the calculation of the CRC getting differences in the process. I then noticed the PROGMEM keyword on the array of CRC values. This seemed suspicious although at this point I had no idea what it meant but I removed it from the next line:

const unsigned char CRC8table[256] PROGMEM = {
to get:
const unsigned char CRC8table[256] = {

And after I did this the crc calculation works consistently – well I always get zero now indicating no errors and at the slow data speed I wouldn’t expect any errors. After investigating PROGMEM I find that it is supposed to put items into flash but was perhaps being used incorrectly as it relies upon a library that doesn’t seem to be being used and also only works with specific data types.

So, in summary, what I found is that the original code was all ok except for the use of PROGMEM. When PROGMEM was used in the definition of the CRC table the calculation of CRC values using the this definition caused some type of memory corruption. This memory corruption led to random errors being seen in the output.

I think I can now get on and start work on the nRF radio transceivers.

Creating a new audio amplifier part 8.

After a bit of a long delay I’m going to call this finished.  I knew it was all working but it had been in a a testing phase for too long so I made a big effort to get the thing done. I’ve redone a lot of the internal wiring and put the front and back panels on.  These are made of an old server lid and are galvanized 1 mm steel sheet.  I had to cut the strips with a cutoff wheel in an angle grinder so I could then use tin snips.  It would have better to use a guillotine.  Steel is I think better than aluminium, it is stronger and I think it works better at shielding.  When I was testing the amplifier with the computer prior to finishing the panels I was getting some kind of electronic noise coming through, now I get nothing.  (I presume it must have been the graphics card that would generate audible harmonics because the rest of the computer would generate signals outside the audio range).

amp_front_covered

The main heat sinks are made from an old industrial air conditioning controller. The heatsink on the bridge is half a heat sink for some old cpu.  Note that the transformer from the old receiver is shielded, it seems to be very quite. The only issue is that I have no idea of the VA rating of the thing.

amp_from_front

I had to do a fair bit of hacking around on the front inner panel due to my not measuring properly where the pots and the audio were going to protrude.

amp_from_back

 

I’ve also replaced the old power switch with a DPDT and included a mains filter (no idea if that is needed) and a mov directly onto the IEC plug.  The speaker / headphone switch is another 240v switch of about 16 A and to the left is the resistor network for the headphone output.  I tried to make all the wires use plugs to make for easy repair.

amp_over_to_right

The heat sinks for the power amp chips are insulated from the chassis so I need no washers between the metal tabs of the chips.  This means the heat sink is at about -ve 30 something volts I think.  I tried to make the wiring as neat as I could and separate the blocks of function so the inputs are at the front of the amp near the pre-amp and the speaker plugs and headphone socket are along the back. This means the signal travels from low to high around from the front to the right and then through the power amp and then to the rear.  240 v is along the lhs edge and the DC is over to the left.

amp_rear

This is what it once looked like.

Receiver purchased for $10 from the tip.

Receiver purchased for $10 from the tip.

The original components in the receiver

The original components in the receiver

Creating a new audio amplifier part 7.

After a long delay I have some more progress photos to show. The power supply is finished and the amp and pre-amp boards are complete. I have briefly powered up the amp board and no issues were found (power rails drop to about 32v from 33v and zero volts on the output.  I could have worked longer tonight but the likelihood is that I might blow something up.  Already getting paranoid about having made some error.  For instance at one point I had turned on the power to check the main supply rails one more time and after I turned the power back I attempted to plug in the power to the amp board, I got a few sparks as the local caps charged up (at least I hope that was what happened)…   As you can see I haven’t tried to make a work of art here. I am more interested in making everything plug-able and hopefully work well and reliably.  There’s a fair bit of work remaining, I have to make up a number of cables for connecting pre-amp power and input / output and controls and switches.  Then I have to figure out how to finish of the case and mount the controls and input / ouput stuff.  I haven’t given much thought to the computer side at all except that this can fit into a gap in the front panel metal work and there is a 10v output in the power supply.  I did get information from the blog about RFI and at the time I had completely forgottten about the computer. (Since my heatsinks are not insulated from the amplifier chips there was concern they would pick up the noise).  We’ll see. Anyway there might be even more delay before the next installment since we are moving house over the next few months.

 

Creating a new audio amplifier part 6.

It has been quite a while since I last posted. I have made some progress, but I hadn’t realized how much work needed to be done. The main problems have been making a mount for the heatsinks, – made worse because I wanted them to be insulated from the chassis – and fitting things into the existing case.Well, in a lot of cases working out how to do this.  I have partially completed the P19 and P88 boards and have a rough idea of how the power supply will be implemented.

Rough power supply layout and board mounting

This is the power supply board showing a vague idea of the locations of some components.  I intend to also mount lm317 lm337 regulators on this board using pieces cut from a CPU heatsink to cool these and the diode bridge. The large terminal block is from the airconditioning equipment that the amplifier heatsinks came from.

 

Aligning the heatsinks

I aligned the heatsinks by clamping as shown with a piece of angle drilled at the distance of the amplifier chips (just fitted into the board not soldered) to make sure the module will fit.  I intend to solder the amplified modules after they are mounted to the heatsinks.

Amplifier positioning

 

 

I clipped the angle to the amplifier modules and then marked the holes prior to drilling. The angle is used to make sure the main heatsinks must stay at the correct distance apart while make the mountings and then when the heatsinks are mounted. After comparing this image with the one from the Elliot Sound site I can see that my heatsinks are easily large enough.

 

 

Heatsinks positioned in the case


At right is shown the heatsinks in their final location. Two cross beams will support them and these will be insulated from the case.

 

 

Partially contructed pre-amp

 

The pre amp board. I did have some problems soldering these boards as they are so small and my eyes have degraded somewhat since the last time I did any soldering. Even with magnifying glasses sometimes I was guessing where to hold the iron.  Luckily I have some lead solder left (I am still using only the second roll I ever bought).

 

I have progressed a little further since these photos were taken. In particular I think I have nearly all the remaining components and have finished the mounts for the heatsinks. I did decide to use plugs for all connections to both boards, this will mean they can be mounted while I layout the wiring since everything will just plug in. Easier for maintenance also. This weekend the rest of the family are going to visit inlaws so I am hoping to get a fair bit done.

Creating a new audio amplifier part 5.

I had some interesting suggestions from the Elliot Sound forum regarding heatsinks and displays.

I am now a little worried about the character based LCD displays. I did recently experiment with a small 128×64 graphical LCD display connected to a 100mhz ARM. I could draw lines on this display seemingly as fast as I could see, so perhaps this might be the way to go. A graphical display gives me more interesting options in any case. I suspect this graphical display allows a faster data rate than the text based displays.  Wastes a lot of I/O pins however and this controller is more expensive than I intended to use (but I have two so I might as well use one).

As for the heatsinks, even through I don’t really want to try to cut them – cannot cut straight with a hacksaw – I think I might try since I want to try to do all I can to make sure I can use the amplifier up to a reasonable power level without problems. I do intend to use the amplifier driven by a guitar so it has to be reasonably capable. I guess this could be easy to test once built if I am measuring temperature just by operating the amplifier in various orientations and logging temperature.  If I did this I would also move the power amplifiers up to the front lhs as this is where the cooling grills in the amplifier case are. I would move the existing heatsink over to the rhs in that case.

I was also thinking today that if there is a processor in the box that it should take a more active role, so for instance using that to soft start the amplifier and to power down on over temperature or other fault condition. Pointless perhaps but fun.

 

Creating a new audio amplifier part 4.

I have made some progress (although I admit taking apart the old receiver is sure to be the easy part of the job.  At present I am still trying to decide between the LM3886 and the TDA7293

This is the amplifier with just the 240V wiring and transformer remaining

We have removed all the circuit boards at this point, I was intending to keep the power supply but it was old and I didn’t trust it.  I know that electrolytic capacitors do age so I will discard them.  I will make a new power supply on veroboard and as a 35A chassis mount bridge as recommended for the power amplifier design.

 

The front panel

 

The front panel turned out to be nice and flat and made out of good solid material. I intend to mount switches, volume, balance and inputs all on the front panel so that small signals are kept away from the amplifier outputs.

 

 

This is the possible location of the heatsinks in the remade amplifier

I should probably be able to fit 2 of these heatsinks, one for each chip amp. The power amplifier board would sit mount transversly underneath these. The heatsinks would be attached to aluminium angle mounted to the case with nylon bolts and washers so as I do not need to use mica washers. I originally thought the case would seem too large but these only just fit. Hopefully this will allow me to run the amplifier a quite high power.

 

 

Planned arrangement of components

The image opposite is planned rough layout. Not that I intend to place inputs on the front panel close to where the pre-amp is mounted. Hopefully this makes a good separation from the outputs. I also avoid having to use any form of extension for pots and switches or long runs of shield cable.

 

Part1, Part2,Part3

Creating a new audio amplifier part 3.

My youngest son and I went downstairs to the workshop / garage this evening and started removing bits from the receiver. He had some fun. I found that the ganged switches are soldered to the circuit boards these will be a little tricky to remove without damaging them. Luckily the switches are also mounted onto an angled piece of pressed steel and so I should be able to mount them without a circuit board.  The RCA sockets on the back panel were also soldered to the board but these should be easy enough to reuse. We dismantled the front panel and I believe it won’t be too tricky to mount a piece of flat aluminium on top of this front panel.

One electrical problem I have come across is (as I have previously mentioned) the power supply that exists is delivering too much voltage for hte LM1875’s but it was pointed out to me today by Rod Elliot that I could use the LM3886’s instead. This would give me a more powerful amplifier but I would have wasted money on the LM1875’s. I could also use another transformer I have but this is about 60VA and would mean a reduced power output for the LM1875’s – this probably doesn’t really matter as most of the time the amp will be driving headphones.  It’s just that once I noted that I could use the more powerful amplifiers chips – I just want to!  It seems ridiculous (but frugal) to use such a big case for such a low powered amplifier.

So I have a conundrum. Making things worse is that apparently there are fake LM3886’s being sold on ebay – I could get a pair for about $12 (free shipping but possibly fake (why would you bother?)) or from element14 for 12 + 12 shipping or from Mouser from $19 + $39 shipping!

Part1, Part2, Part4

Creating a new audio amplifier part 2.

Receiver purchased for $10 from the tip.

I found this old thing at the Tip Shop, it was $10.  When I plugged it in it fired up and it seemed to mostly work – I could listen to the radio with it. The balance control was noisy and there seemed to be some weird issue with the tuner. Anyway I intend to gut it and make use of the power supply etc. Unfortunately upon measuring the rails I find +/- 33 volts which is a little high, also a max of about 125mv of hum which I am not sure is good or bad. In any case I think I need to use some regulators to drop from 33 to 25. I think I could use a set of LM317 and LM337 chips but I need to find out how much power the LM1875 uses at 20W output.

The original components in the receiver

The inside of the receiver is shown. Most of this will go apart from the power supply (top right) and the heatsink (which I will use to shield the FRDM KL25Z). I also not that there is a 4 way ganged switch at the front which I will make use of as an input selector (this doesn’t appear to be soldered to a circuit board but is point to point wired – which make it a lot easier to utilize)

 

 

 

To the left is the heatsink I intend to use for the power amps, it is currently mounted on some kind of air-conditioning control circuit.  This is about 20cm long, 6cm high and 10cm wide. I think it should be enough.

 

 

As for the front panel I think I might try to completely cover the front panel in a sheet of aluminium just leaving input selectors, volume (the largest knob), LCD display. I might even forgo a balance control.

Anyway the main task is to design the power supply modifications.

Take care.

Part1, Part3, Part4

Development boards

I am currently learning to use the Blueboard LPC1768-H and the FRDM KL25Z.

FRDM KL25Z

These are reasonably cheap Arm processor boards with a lot of peripherals and IO built in. The FRDM has a 3 axis accelerometer for instance and only costs $9 – which is amazing.  Additionally the FRDM can have a software change to make the board mbed compatible. mbed is an online compiler with an API for embedded ARM based controllers that is provides the same API across a range of boards.

Blueboard driving an LCD

After using the mbed system for a short time I have become a fan, the benefits of being able to just drag the compiled code to a mounted drive, to have integrated version control, a simple consistent API across the different features of the board, many user written libraries easily dragged into the project along with printf based debugging through a USB hosted COM ports out weighs the lack of a true debugger.

It is possible to easily manipulate the hardware including using interupts, timers, accelerometer and even I2C for example without really need to worry in detail about an bit manipulation of the Arm registers.  It is not that difficult to figure out the bits but it is confusing an error prone and gets in the way of thinking about the code.

I am able by comparison to get work done using the Blueboard and the Open source CooCox compiler (which allows me to debug using the JTAG board).

The USB – JTAG interface

However the CMSIS libraries provided for Arm libraries are not quite at the level of ease of use of the mbed stuff (partly due to the lack of documentation as there are things I keep finding).

One of my main goals for these boards is to make toys – I have ordered various sensors of ebay and along with the on board accelerometers I think I can produce something intriguing. Well I hope so.

 

Creating a new audio amplifier part 1.

Since my old amplifier (which I purchased second hand of ebay quite some time ago) is now  connected to the TV I decided that I wanted to build a new one. This is the amplifier that I use for the electric guitar and for the computer. I have also for a long time wanted to build some of the kits from the following website . In particular I wanted to build project P88 a PreAmp and P72 a 25W / Channel power amp based on the LM1875 (which is the basis of a lot of the gainclone amplifiers). As I was ordering from element14 (Farnell) and wanted to make the order up to $45 I quickly bought the Op-Amps, power amplifier chips and some Pots. I will soon purchase the PCB’s from Elliot Sound and start sourcing the resistors and capacitors (hopefully these will be in my store in the garage).

All was good.  Until I started thinking about the case and the transformer.  Transformers in particular are expensive and in this case what is specified is at least 150VA at 18v-0-18v. This would cost around $70 and a nice case around $30.   This is in comparison to the IC’s which were all up less than $15.  Added to the price of the PCB’s ($40) and this is not looking very cost effective.  (Note I have heatsinks downstairs in my junk collection, luckily).

So I went out on Sunday afternoon to the shop at the tip and found an old Akai reciever and managed to get that for $10.  On getting that home I found that it turned on and worked – it didn’t sound that good but at least the power supply and transformer seem ok.  Given that the amplifier in the Akai is around 25W I am hoping that the power supply can be used to drive the LM1875’s i.e. not more than +/- 30V.  The case is good too – except rather large.

So the plan is to gut the receiver leaving the switch gear (which seem to be mounted on the frame rather than the PCB), the rear panel connectors and the power supply board and transformer – meaning also that I don’t need to touch any 240V wiring.  I haven’t yet worked out how to deal with the front panel and I don’t think I can make it look like some of the cases I have seen made for gainclone amplifiers, unfortunately the tuning dial will probably need to be covered up.

Interestingly given that the power capacity of the original amplifier and the LM1875 amplifier’s are roughly equivalent size difference is amazing.  Although I think the heatsink I will need to use will end up larger.

Once the amplifier is working I want to add a 40 x 2 character LCD display powered by a FRDM KL25Z board (3 of which made up a part of the element14 order) these are Arm development boards costing $9 each. I want to display peak and average power, temperature and input selection on the display.

So, the plan is:

To gut the existing amplifier to leave the power supply, suitable connectors, switches and knobs

To build the new PreAmp and Amplifier boards

To strip the heatsink for the amplifier (from an air-conditioning controller board I have)

Figure out how to wire these boards to take advantage of existing connectors and switches

Reuse the aluminum knobs for volume and balance.

Tidy up the modified front panel including mounting the LCD display

Build a power monitoring circuit

Program the FRDM board to monitor power, temperature and switch positions.

Thats all I have for now, I will take some pictures along the way.

Part2, Part3, Part4