Sunday 8 March 2015

Reverse camera overlay hack (removal)

A while ago I purchased a reverse camera from ebay. It turned out to be NTSC and I got a refund because I needed a PAL one for a peculiar monitor. I got to keep the cam, so I was hoping to use it in some projects, but as it turns out it is mirrored and it also has a nasty overlay on it.


As such it was lost around my house for a while, until yesterday when I needed a camera so I plug it in and remember that the image is mirrored, and perhaps I should get rid of the mirroring and the overlay while I am at it.

(24c08) the mobile phone dvd lens magnifier was useful
Some searching revealed a single thread which showed the I2C chip can be disabled by shorting the SCL or SDA pin to ground. This will disable the eeprom and use whatever defaults the camera IC uses. That means mirror / pal/ntsc could change, and possible image corrections, too. Note this only works with I2C chips, some chips use SPI which will not like a pin shorted to ground( damage will occur). The SPI chips need disconnected power pin.



I tried this and it works on this camera chip, but the image is still mirrored, although the overlay is gone. As such I commenced searching for more info. I found the camera chip is PC1030K , and even found a datasheet for it on a strange site. Why does this not happen on all the other searches I do?

It turns out there is a hardware configuration using pull up/down resistors on 8 pins used for digital data output. Those could be set to for mirror / pal /ntsc/ flicker removal frequency. The settings are only read at reset. Details in the datasheet. http://download.csdn.net/detail/chelsea3q/7164049

Since I already got this far I decided to actually reprogram the EEPROM to make the camera more suitable for my needs. Also because it's fun, too. The datasheet has info about this, but due to the way the memory is read and switched between banks of registers I still needed a bit of time to find the right settings.

I interfaced an arduino UNO to the camera on the SCL, SDA lines, which (seem to?)use the standard I2C protocol ( named SCCB in the datasheet) . Reading the 24C08 memory was not very hard and I did it while the camera is on since I2C can have multiple devices on one line. ( technically not 2 masters, however). My arduino uses 3.3V , it is possible that the camera's 2.8V is too low for a 5V arduino to trigger a HIGH level read.

I changed a number of settings in the last couple of days, and there are no real issues programming the EEPROM. I disabled edge enhancement, after which the camera's real image quality can be seen (a lot softer , but less noisy) . Of course the overlay , mirror , gamma and some others, but there are a lot of other settings I still want to try out. Compared with other CMOS image sensors, this one has probably a minimal set of registers. The EEPROM contains about 300 values, but the chip itself about 700 registers.

I was unable to access the main IC directly, it appears that perhaps it does not listen on i2c if an eeprom is present, or perhaps an undocumented pullup like the PC6030 chip uses ( by the same company PixelPlus ) on the vsinc pin can set i2c master/slave mode. I tried every address / register combination just to make sure.

I am still to disable the auto white balance (AWB) compensation and tweak some auto exposure (AE) parameters, but apart from this I am finished with this project since a new, lighter camera will arrive soon.

The PC1030 sensor device is one of many camera ICs commonly used , some other are in the image below:


Another PC1030N ( this time) datasheet :http://wenku.baidu.com/view/a44f0a13a216147917112877.html?pn=51 ( seems identical)



















Tuesday 16 December 2014

Arduino air flow meter "test"

This post is about a device to measure air speed for use in a RC plane when a suitable version is designed. Unlike pressure based devices, I went with a thermistor version that is built with cheap parts. Also, the use of thermistors should result in a sensor with a lower minimum measurement value, but has a smaller range of operation.

Anyway this is only a proof of concept to see what can be done using only an Arduino and no opamps or additional electronics. Suprisingly the device worked quite well, although not really suitable for an air speed meter due to somewhat small dynamic range and slow response ( to be rectified in a future version) The response is of about 5 seconds with a thermistor 5mm diameter.


Basically the arduino is outputting a current to the thermistor ( TH1 ) and thus heating it in order to keep it's temperature a constant amount above air temperature. Any airflow over the thermistor will cool it, therefore requiring a higher current to keep the temperature constant. The second thermistor is used as a reference, in order to keep air temperature changes from appearing as air speed changes.

This is all quite simple, it's actually quite surprising I have not found a similar project. Anyway, the main problem of this design is the current and voltage the arduino can source, so limiting the max power that can be output to the thermistor. This is main reason for the low dynamic range of the device right now.

Due to above limitations, a suitable thermistor has to be found so that it's resistance is not too high ( we only have 5 volts supply) and not too low ( we only have 20 mA) Yeah, perhaps an extra transistor might be the way to go here. Anyway I settled for 2x500 ohms NTC thermistors because this was the shop had, and i'm not waiting months for parts. Note that a suitable range is probably 250 -  750 ohms.

The 1k divider resistor is also not important, it's there as a pull-up for measuring the thermistor temperature. A higher value could have allowed me to use analog 1.1V reference, and possibly add some resolution, but this was the prototype.

The sensitivity is probably better then the human skin and the max readout is somewhere around 5km/h (guess). It could be used for checking if a fan is functioning, or to close a window if there is too much wind coming through. It can also sense airflow made by people walking by it.

For testing it could be covered with a cup, it can easily sense random air currents and breathing.

Some more things about it in no particular order.
  •  not very linear
  • good low speed accuracy
  • low max readout
  • zero reading at an arbitrary offset ( needed to heat the thermistor)
  • slow transient response due to thermistor mass ( 5 seconds )
  • needs setting a pid
  • might be sensitive to infrared if it hits only one thermistor
  • might be sensitive to air temperature to some degree
  • directional to some degree due to thermistor shape
  • needs startup time of several seconds
  • it surprisingly works
  • could connect resistors to vcc to save pins
  • maybe even use internal pullups and 1.1 analog reference.
  • could be improved by accounting for thermistor nonlinearity and also voltage divider nonliniarity
To calibrate:
To find a good start TEMPDIFF write a sketch that sets pwm to about 80 or modify this one to a constant pwm and read the difference between the start temp and the "heated", or between the 2 thermistors.

To set the pid i have no real guidelines since it depends on everything else, but the kd should be left at zero at least until everything is working fine and better transient response is needed. Thats because most of the time the input will change by only one LSB and as such the kd term only adds noise. The kd term is why I tried to add some averaging.

I started my pid with the ki term, which I increased until the sensor heated up in a few seconds.
Of course with only ki term there were large oscillations , so I added some kp to compensate.

too much overshoot over a few seconds means ki is too high , or kp too low.
oscillations of fast period is probably kp too high.
Pids are always fun but the most fun are the ones made by other people :)

The real method involved some calculations, too.

 the sketch:

// released under The MIT License (MIT)
// basically any use permitted - please look up your copy somewhere else
//
// Arduino sketch to detect airflow using 2 thermistors, 2 resistors
// 1k from r1pin to analog1 and pwmpin ; thermistor1 from analog1 and pwmpin to gnd
// 1k from r2pin to analog2 , thermistor2 from analog2 to gnd.
// thermistors 500 ohms in this version http://www.jaycar.com.au/products_uploaded/RN3434.pdf
// silverx 2014
//

const int pwmpin = 5;   // this pin has to be pwm capable
const int r1pin = 7;    // digital out pin
const int r2pin = A5;   // digital out pin
const int analog1 = A0;    // analog input capable pin
const int analog2 = A2;    // analog input capable pin

// PID constants depend on thermistor size, resistance and thermal constant
// this will need to be found for a particular thermistor
const float kp = 20.0;
const float kd = 10.0;         // kd should probably be zero in most cases
const float ki = 1.0;

const int TEMPDIFF = 40; // difference to maintain between thermistors ( in analogread units)
                         // positive for NTCs
void setup()
{
 
  Serial.begin(57600);
  Serial.print(F("Thermistor airflow test sketch\n"));

  pinMode( r1pin , OUTPUT);
  digitalWrite( r1pin , HIGH);
 
 // analogReference(DEFAULT);
 // analogReference(INTERNAL);
 
  pinMode( pwmpin , OUTPUT);
  //digitalWrite( pwmpin , 1);
 
  // we could warm up the thermistor here for a few seconds
  // that will avoid the full scale read at startup
 
  pinMode( r2pin , OUTPUT);
  digitalWrite(r2pin, HIGH);
}

// filter made by online generator at
//http://www.schwietering.com/jayduino/filtuino/index.php?characteristic=bu&passmode=lp&order=1&alphalow=0.01&noteLow=&noteHigh=&pw=pw&calctype=float&run=Send
// this filter is about 0.1 Hz ( 10 seconds) ( 1 / 0.01 * 100ms loop)
//Low pass chebyshev filter order=1 alpha1=0.01
class filter
{
    public:
        filter()
        {
            v[0]=0.0;
        }
    private:
        float v[2];
    public:
        float step(float x) //class II
        {
            v[0] = v[1];
            v[1] = (3.053896819732e-2 * x)
                 + (  0.9389220636 * v[0]);
            return
                 (v[0] + v[1]);
        }
};

filter lpf, reffilter;

float outpwm = 0;
//int treshold = 280;
//int lasterror;
float integralterm;
float lasterror;
float roundingerror = 0;

void loop()
{
  float input = 0;
  float ref;
  int treshold;
  float airflow;
 
  digitalWrite( r2pin , HIGH ); // R2 pullup on
 
  ref = analogRead(analog2);  // read thermistor 2 ( reference)
 
  digitalWrite( r2pin , LOW ); // pullup off ( so it does not heat up the thermistor )
 
  ref = reffilter.step(ref); // filter the reference with a low pass filter,
                             //  otherwise it will add (a little) noise
                            
  treshold = constrain ( ref - TEMPDIFF , 0 , 1024);  // this is what the pid tries to get to
 
  pinMode( pwmpin , INPUT); // turn off the pwm pin or we can't read the thermistor
  pinMode( r1pin , OUTPUT );  // turn on pullup R1
  digitalWrite( r1pin , HIGH );
 
  for ( int i = 0 ; i <10 ; i++) // even a single read works
 {
  input = input + analogRead(analog1); // read thermistor 1
 } 
  input = input / 10;
 
  pinMode( r1pin , INPUT ); // this adds current through the thermistor
                            //  and pwm ( sink) if left on (but still works)

  pinMode( pwmpin , OUTPUT); // we can turn on pwm again
  analogWrite( pwmpin , outpwm);


 // this is for checking
  Serial.print( input );
 
  Serial.print( " " );
  Serial.print( ref );
 
  float volts = (float) 5000.0 * input / 1024 ;
  float resistance = 1000.0 * volts / ( 5000 - volts );  // r1 = 1000 ohms,
  float power = 5.0 * 5.0 * ( (float) outpwm / 255 ) / resistance;
 
//  Serial.print( " v:" );
//  Serial.print( volts/1000 );
 
//  Serial.print( " th1:" );
//  Serial.print( resistance );
 
//  Serial.print( " p:" );
//  Serial.print( power );
 
  Serial.print( " " );
  Serial.print( outpwm );
 

float error = input - treshold; 

// this is the PID which heats up the thermistor
 
  outpwm = ( kp * error  + kd * ( error - lasterror ) + integralterm * ki );
 
  lasterror = error;

  integralterm = integralterm + constrain ( error , -128 , 128 );// not really needed
 
  integralterm = constrain( integralterm , -25 , (float) 255 / ki ) ; // prevents integral windup, especially at startup,
                                                                      // but at full scale output too.
 
//  Serial.print( " " );
//  Serial.print( integralterm );
 
//  Serial.print( " " );

  airflow = lpf . step(outpwm);     // the pid out is the sensor output, the filter removes some of the noise
                                    // the ki term can also be used as an output
  // should be used between 0 - 255
  Serial.print( " airflow:" );                                 
  Serial.print( airflow );
 
  outpwm = constrain( outpwm , 0 , 255 );
  Serial.println();
 
 delay(100); // variable loop time will affect the pid coefficients and the low pass filter
}

// END OF SKETCH


















Friday 24 October 2014

NRF24L01+ and data whitening (arduino)

25.10.2014

The NRF24L01+ IC is a cheap and relatively versatile way to add radio transmission to a project, however this versatility comes at a price: Some features and controls are not included, such as modulation and encoding types, PLL and IF settings, RSSI adc, etc.

This post investigates if data whiting, which is included in some competitor's chips, would actually provide an improvement at longer range transmissions. Said missing data whitening could be implemented in software,  but the performance benefit must be present in order to make best use of available resources. There is also the possibility that whitening could have a negative effect. ( which turns out to be true)

Whitening works by attempting to break up long chains of zeroes and ones that may occur because of the particular data being sent. This is done by XORing the data to send with a known string of random numbers, and repeating the process at the receiving end with the same numbers.

Anyway, for the practical side of the test I used ( in the first tests) an arduino controlled mobile NRF tx and a similar static rx, with it's accompanying arduino connected to my PC for logging. The speed was set to 250k, no shockburst, 10 bytes payload of which the first and last were zero and soft crc respectively.

For measurement I have logged the percentage of received packets filled with repeating 8bit data. Each packet would be sent a number of times to find a receive rate. For this test I used approx 1000 packets for each value tested.

After doing this for every 8 bit number I hoped I will have a result of the possible effectiveness of data whitening. I had doubts about the effectiveness of this test, because 2.4 Ghz is very susceptable to multipath propagation. While running a test for several hours, things like people and cars moving make differences in reception. I used 2 alternating channels since the software already had that feature.


Each pink dot represents 100 packets.

In the above image a gap just before 128 can be seen, which implies it is caused by multiples ones.
A similar gap is present before 64, too. Also the above data is somewhat repeatable, but a lot of noise is masking a definable pattern, while also not excluding other, non whitening related mechanisms. For instance, the frequency modulation (GFSK) could be subject to different propagation or multiple paths, or interference from other devices  could be the cause ( jamming more ones, for example).

I decided it was probably interference , but I still tried some more tests. At this point I changed the amount of channels the NRF used in order to exclude some frequency related mechanisms. I figured 8 channels should be of benefit.


the highest light blue line is the sum of all channels. the 45 degree line is the binary number transmitted. There were probably 500000 packets sent for this ( measly) graph.

In the above graph "helped" by some image editing, it can be seen that the drop before 127 is still there. But you have to be very optimistic to see a pattern in this graph, and humans are known to see what they want to see, too.

Using 8 channels did not help much, in fact one channel was usually not receiving anything due to positioning, or swinging up and down adding noise to the graph. Anyway, i needed a better method since this is not repeatable, and drops in rf transmission add noise to the actual data needed.

Since using incremented values of payload did not work so well I changed to a different scheme, using random numbers instead as to mask the slow moving propagation changes.

The random number rx software needed a different method of counting packets and so i placed each received packet in a "bin" depending on it's value. I used 256 bins, and stopped the test when a bin reached 255, since arduino is somewhat low on memory. ( 255 was not transmitted due to the arduino random() function not including the top value)

The internal arduino number generator  is used ( c++ ) and as I understand it shouldn't have any problems dividing the data in between 8 channels, since 8 is a pretty low number.


As usual, I thought this wasn't good enough. I thought perhaps, using random numbers was not the best idea since they are basically white noise, hence adding noise to the graph. I didn't know it at the time, but differently arranged the graph makes quite a good point about the efficiency of data whitening.

Next, and last (at least for now) test involved replacing the random number generator with a " random sequence" 255 bytes long. I figured the sequence will reduce the noise overall, since each number will be transmitted the same amount of times as any other. The 255/ 8 channel combination is less then ideal, but at least it is not a multiple. Luckily the LFSR pseudo-random sequence generator can only generate 255 bytes long sequences instead of 256. Zero was not included this time, for a change.



The line type graph makes the data look a lot better, at least to me, an XY graph is actually not so different then the previous test . Of course, I have been staring at lists of binary numbers quite a lot lately, so I can hardly tell.
Arranging the data by number of ones can show exactly what is happening:



In the above graph the values are arranged in order of number of "ones" out of 8, ascending. It becomes clear that sending a lot of ones is a really bad idea. Sadly , for data whitening to work the same has to be true for zeroes, and that is not true here, at least for the settings used.



I originally thought that reception might be affected not only by one/zero ratio but by amount of consecutive ones ( or zeroes) . In the above (unlabeled) graph I plotted the same data arranged by number of consecutive ones, ascending  ( the ones are counted including neighbours ) . This is very similar to the previous graph. In case you can't tell, the linear regression line is at the same angle in both. To me this means the consecutive-ness of ones is not affecting reception much.

In the graphs there are some spikes that may imply a second influencing pattern. However, there is still a lot of noise, and people, I included, are very good at seeing patterns in random data that are not actually there. One such pattern seems to be 01010000 and it's shifted relatives.

In conclusion, the NRF24L01+ chip ( non fake / copy, etc) does not include data whitening because it would achieve not much. For my application , I decided to use RLL codes (  run length limited ) specifically a  GCR: (0,2) RLL code (inverted) that originally was used for magnetic media. I will probably implement them any day now. Since such codes are 4 to 5 encoding, and as such 8 to 10 they will require a slightly longer payload. That opens a whole new can of worms.




















Thursday 21 August 2014

ESC capacitor for RC brushless motors

In the process of upgrading various things on my plane, eventually my attention reached the capacitor connected in parallel with the battery, as part of the ESC. Some questions that arise are: Is it really needed, what is it's optimal size and what ESR should it have.

I proceeded to find out if it could have any effect by finding the impedance of a Li-Poly at frequencies such as those used in this application. The ESC uses 8KHz PWM when under 100%, so if battery ESR degrades after 8Khz a capacitor could, potentially, help. Sadly information about the impedance of Li-poly batteries vs frequency is not that easy to find. In total I only found 2 graphs, but luckily they agreed pretty well. In them the impedance starts rising at just about 10Khz, interestingly enough. That could mean the higher harmonics of the 8KHz PWM could potentially use the capacitor.

 Testing:

Next comes the testing part. I used the RC plane with an adapted 1000uF low ESR capacitor and a switch in between the battery and ESC  . It uses it's own piggyback connectors which I usually use to measure current. Overall the leads are still very small,  about 10 cm. The battery is 7.4 300mA, a rather small size for RC. The motor draws max 3.5A. The ESC still has it's 100uF capacitor.

I used partial throttle and measured RPM to check if any difference exists when the 1000 uF capacitor is switched in and out. I was surprised that a difference in RPM can actually be seen, but it was very small and hard to measure since the the RPM changes by itself to some degree as well. I eventually obtained several values so that the improvement can be quantized.

After plugging the numbers in various wab pages and programs, I came up with the following: The RPM is incresed about 0.15% to 0.30% at partial throttle. I checked only the lower 1/2 of throttle range since measurement accuracy was too low for the top half.

The RPM increase is very ( or is it fairly) small, but the result gets slightly better when the thrust vs rpm formula is used. I looked up the propeller used ( 6030 GWS copy )  and it's thrust (g) =  6.3e-007*(RPM^2.1) .

After some juggling the thrust percentages work out to approximately double: 0.24 to 0.67% . Note this includes errors so the real answer is probably about 0.3 - 0.5% increase. This hardly justifies the addition of a capacitor where lead size is small, but at least is shows an actual amount of improvement exists.

Calculating optimal capacitor size:


The battery internal resistance and the capacitance form a filter, which I wanted under 4KHz so that it may possibly improve impedance at the ESC. As such the capacitor is proportional to the battery ( and leads) internal resistance as in the formula :  C = 1 / ( 2* PI * Rint * frequency  )

The frequency chosen is arbitrary since the battery impedance is not known. As such you could use the actual pwm frequency, or a lower value such as PWM/3 for more extreme cases. If capacitor ESR is not low enough compared to the battery internal resistance ( it should be similar to it or lower)
using larger capacitance values will not do much, as the ESR will be the limiting factor. If cap ESR is higher then say, 2x battery internal resistance the capacitors will likely not do anything.

Scope comes out:


After all this I wanted to see what actually happens, so I hooked up the scope and looked at the waveforms trying to connect what is happening to where. A look at the (unsteady) motor waveform did not show anything changing. I soon realized I was not going to see a 0.5% change on a scope screen. But I reluctantly connected the probe to the battery, where the capacitor is connected. (not a very good place, really) . I could then see a 80mV sawtooth-like voltage drop reduce to a 50mV drop.
As luck would have it, the change is of the right magnitude, i. e. zero point something percent.
I will accept this result due to the fact this has used up more time then necessary for the potential improvements.
 Above waveform with no cap, under waveform with cap. Waveform needs mental inversion.





Overall, it looks like the cap provides some more voltage , like I assumed, by reducing the voltage drop. Since the cap has to charge from the battery on the off cycle , it will not do anything at full throttle, where no PWM is used. But, since the cap increasees thrust at partial throttle, it's effect is no different then increasing the throttle manually by 0.5% . As such , in my case the weight and size of the cap is not useful ( in a plane) in exchange for a throttle offset.

This does not account for long leads, where voltage spikes could damage the ESC ( or the cap). It also does not cover reverse current flow (into battery) from regenerative breaking. Such applications do, and could, respectively, benefit form capacitors.

In other applications, where batteries with much lower internal resistance are used, it is hard to believe the capacitor ESR can account for a high enough fraction to make any difference. In such cases good quality, low ESR capacitors could be paralleled together.

It is likely the capacitor/s could help more in aging, higher internal resistance batteries, but, overall, since there is no efficiency improvement, the capacitor can't overcome the bigger problem that, after all, partial throttle is, well , something arbitrary.





from "Fast Estimation of State of Charge for Lithium-Ion Batteries
Shing-Lih Wu  , Hung-Cheng Chen  and Shuo-Rong Chou "



A schematic of the resistances involved, the 47uF cap is actually 100uF .








































This page has been intentionally left blank






Friday 7 March 2014

Arduino analogWrite with higher resolution

The other day I was troubleshooting a project that did not work as intended, so I eventually put down the problem as inadequate resolution. Even after averaging analogReads, reducing truncation errors and optimising everything it did not work much better.

Of course, ultimately the PWM analogWrite resolution is 8 bit on the Arduino UNO and my project did not even use it's full range, which limited it even more.

After some looking around I actually found out the atmega328 chip supports much higher PWM accuracy, up to 16 bit if necessary, but only on pins controlled by timer1. So I came up with a modified PWM routine that uses 10 bit resolution. (the 16 bit is a bit overkill once considering supply variations)


This is used by calling analogWrite10bit( pin , value); just like the original one but with 0 - 1023 range; Only timer1 pins can be used. That makes for pins 9 , 10 on the UNO and other atmega328 Arduinos. Once called even for one pin you can't use normal pwm on EITHER pins, so you have to use this routine for both.

Not tested on mega, leonardo but might work on corresponding timer1 pins.

//
//      GNU LESSER GENERAL PUBLIC LICENSE
//        Version 2.1, February 1999
//
//
// this was modified (slightly) from the arduino source code
//
// works on pins 9 , 10 on Arduino UNO
// once used *both* pins are set to 10 bit mode and "normal" analogWrite will not give correct results.
// uses timer one

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

void analogWrite10bit(uint8_t pin, long val)
{
  // We need to make sure the PWM output is enabled for those pins
  // that support it, as we turn it off when digitally reading or
  // writing with them. Also, make sure the pin is in output mode
  // for consistenty with Wiring, which doesn't require a pinMode
  // call for the analog output pins.

  // set 10 bit mode

  sbi (TCCR1A , WGM11 );
 
  pinMode(pin, OUTPUT);
  if (val == 0)
  {
    digitalWrite(pin, LOW);
  }
  else if (val >= 1023)
  {
    digitalWrite(pin, HIGH);
  }
  else
  {
    switch(digitalPinToTimer(pin))
    {

#if defined(TCCR1A) && defined(COM1A1)
    case TIMER1A:
      // connect pwm to pin on timer 1, channel A
      sbi(TCCR1A, COM1A1);
      OCR1A = val;
      break;
#endif

#if defined(TCCR1A) && defined(COM1B1)
    case TIMER1B:
      // connect pwm to pin on timer 1, channel B
      sbi(TCCR1A, COM1B1);
      OCR1B = val;
      break;
#endif

//    case NOT_ON_TIMER:
//    break;
  
    default:
    analogWrite(pin , val / 4);
 
    }
  }
}



Wednesday 6 November 2013

Coaxial SPDIF output for computer motherboard

So, I was walking around the shops with my girlfriend and I see a Battlefield 4 poster. I ask my g/f " This game is coming out sometime soon, right?"  "I don't really know" she probably says. I really don't remember these kind of answers. When I get home I search the net and find out it is released on 31 Oct (2013). It is 30'th. Something needs upgrading, My computer was state of the art years ago. So here come all sort of charts , cpu and gpu performances, and I decide to get a new cpu and motherboard, and hopefully get away without a new graphic card.

All that worked out quite well, except for the crappy socket 1150 cpu heatsink. Intel has changed the hole pattern by about 1mm, so all your old coolers that were designed for 125W cpus and would work fine on a 50W cpu are now rubbish. The stock cpu does get very hot. It got today to within 2 deg Celsius of it's limit, and it's only spring here in Australia. But that will get fixed as soon as I get my Noctua cooler mounting kit. It's free, too. Now that's good customer support.

This is about the sound issues. It seems in the time between my old motherboard and this one the industry has, for some strange reason, changed from the coaxial SPDIF output system to the apparently more fashionable optical system. I mean why use a coaxial cable with RCA plugs when you can use an optical cable that has no other use whatsoever, and it's even cumbersome to use. Times any rca cables have accidental become unplugged: zero .Times TOSLINK cables have become unplugged for no reason: at least one. And this is not only computers. When I was looking for a car stereo, the only one with an digital output was optical, too. Not so only a few years ago. Too bad they were way out of my price range.

Luckily there is an internal connector marked as digital output on the motherboard I have purchased. All I have to do now is drill some holes , make an adapter and hopefully we have sound. Yes, I could use the onboard sound, but it's really really terrible, especially if you plug headphones in it, like I had to do for the couple of days in which playing the game was a *much* higher priority.

The good news is it was easy to make such an adapter. It's only a couple of resistors, and the rca plug. All I had to do is measure the output to find out the voltage, and modify it to suit the coax SPDIF consumer standard which states 0.6V peak to peak signal.
So, after balancing the scope precariously on my computer chair, I had to measure the signal quickly. That is because my girlfriend was complaining about the noise the scope makes. In those days they had to put fans on things, or else they might not last 40 years. But, as usual, something was not working right. There was no signal. I , of course, start checking if there is a ground, if the scope is actually working (it was), etc. My girlfriend was not impressed. Eventually I figured out that, unlike my old realtek soundcard which played the output to both digital and analog simultaneously, this one only plays to one, or the other. Of course, this was one of the things I checked, but it turns out I had to reopen the player for the changes to work. Simple, really.

So, the signal is close to 3.3V, which means I needed a simple voltage divider and an rca plug. The ringing in the picture is from the scope. The divider works out to 75 and 330Ohms.
Note: Vin is on the motherboard side.  Vout is the rca plug middle pin. Refer to your motherboard manual to find out the pins.

The only other advice is to use in insulated rca socket in order to avoid a ground loop. Computers are really noisy and any ground loop will add jitter to the signal. Perhaps an optical sort of plug is required...

All in all this whole ordeal lasted only about , say, an hour. An adapter from ebay is surely, under $20.
I would like to believe an hour of my time is worth more than $20. The only thing I saved was the waiting time from ebay.

P.S. imho optical cables (really, the receiving socket) are very slow, and noisy, which is not good if low jitter is desired. My audio system is not earthed, and a coaxial cable does not introduce any ground loops. Jitter may or may not be an issue in audio, but I can measure it, and I can reduce it, too.
It is even possible that some jitter can be desirable, by masking and other mechanisms. The jury is out for now.


Tuesday 29 October 2013

Subaru 22680 AA160 green airflow meter (AFM) dissasambly

Here are some pictures of my Subaru Liberty's (first series) AFM (air flow meter) which I removed from the car in order to troubleshoot what i perceive as a minor loss in performance at low rpms.

 After removing the rubber and breaking small bits of the case (nothing major) a nice copper screen is found.
 After the screen is gone the somewhat basic circuitry is not much to look at. It looks like the green transistor functions as a heater. The ceramic (?) main pcb has a couple of diodes which might be used to keep the temperature constant. The fifth pin, not connected internally is 5V on the harness. 
After desoldering the top board I found that this is about as much as this afm is going to be taken apart. The board is glued to the backing heatsink. Anyway, there is not much else to look at. The 2 screws hold the inner thermistor assambly. It could be removed  if needed.

I have not found out much during this exercise. The AFM uses unregulated 12V , but there is a regulator in the IC so that does not matter. The meter works, but presumably the printed film resistors or the thermistors are aging. I measured the thermistors as 530 Ohms for the small one and 20 for the larger, rectangular one. They are both PTC. (room temp 22C). With a hair drier they changed to 586 and 22.5.

My array of tests were mostly for fun. The AFM could be used to measure wind speed, but sadly I cannot think of a use for it right now (or ever). It's response time is good moving to higher amounts, and fairly bad from high to low (1 second). Output ranges from 0.2 approx at zero to 3V at my hairdryer's output (probably higher). The hairdryer was surprisingly repeatable with 1% error if placed in exactly same position.

Some error seems to be introduced by air temperature, but it was very small. No error is introduced by power supply voltage.

Since the grounds are connected together there might be ground loops present. I will look at the car wiring diagram in hope ground can be improved.

In conclusion if the afm calibration is off due to aging no used afm will be immune to it. Even new "old stock" units might have this problem. But without any reference there is no way to measure this item's calibration.