Contribute
Register

Kiwi's Next Project - iMac G5

Status
Not open for further replies.
I had thought of this to, my only concern is any additional noise introduced, or picked up by addition of relay will be amplified potentially into audio range. At least with switching on output of the amplifier noise shouldn't be an issue.

I think this will be no problem, because those TAKAMISAWA relays are designed for audio applications. I've also used them in my DIY HiFi amplifier as input selector. Works fine and the sound quality is superb:
20130131-1312801.jpg


I am also concerned with, but haven't resolved, seperate of Gnd planes between audio, and arduino sections of the PCB, don't want all the pwm signals to cross over into the audio circuit

Good, if possible. But not really an issue, as long as you have a heavy GND connection between the NUC and the SMC board.

This leads to a bigger problem with my pcb layout, the main AMP and the chime are not in close proximity to one another. If I remove the lm317 regular from my design, then get some more flexibility, but I cannot see an obvious basic layout, that is small and keeps audio seperate

Why did you change the audio amp? You will loose the available area below it. You could mount the LM317 vertically. Or use BJT transistors without heatsink (driven in PWM mode instead in linear mode, so no heatsink is needed).

I have ordered a scope, see "eevblog #703", an overkill proberly

I think it's a good choice. I would like to have one too...

I have been investigating Fan speed detection on an Arduino, and think need to challenge your statement. The basic principle for FAN rpm measuring is documented here http://playground.arduino.cc/Main/ReadingRPM

I've tried all that. It never worked in context with the SMC sketch. I guess, for example because there are while loops inside the CapacitiveSensor library. If I remember correctly, servo judder was a problem and serial communication did not work properly. Maybe I'm just too stupid...

MacTester
 
Hi Kiwi,



how absolutely amazing job !!!:headbang::headbang::headbang:!!! I just found out that you had to find a way to control the brightness via Mac OS X ....

Part 7 - Microcontroller

Introducing my Micro-controller, the Arduino. So sorry no PIC AXE here, but I hope by the end of this project you will see the reasons for my choice.



More to follow...

that's exactly what I need for my power iMac mods !!! this will concern my last last last step because it will control not only indispensable function for my use: brightness and sleep LED control , and the start chimes....
kiwi thank you for this hard job and your contribution !!!

cordialy

spong_jojo
 
Just a couple of updates.

FANS

I took apart my iMac and wired two of the fan tachometer pins to the two (available) interrupt pins that I had. Then did a very basic implementation of the fan speed detection in my main SMC code. It uses the internal pullup resistor, counts pulses via interrupt, and most important It works well,

Here is an excerpt

Code:
volatile long fan1RotationCount;
volatile unsigned long fan1TimeStart;
volatile long fan2RotationCount;
volatile unsigned long fan2TimeStart;

void interrupFan1() {
  fan1RotationCount ++;
}

void interrupFan2() {
  fan2RotationCount ++;
}

void setup() {

  pinMode(0,INPUT_PULLUP);    
  pinMode(1,INPUT_PULLUP);    

  fan1RotationCount = 0;
  fan2RotationCount = 0;
  fan1TimeStart = millis();
  fan2TimeStart = millis();

  // interrupts
  attachInterrupt(2,interrupFan1,FALLING);
  attachInterrupt(3,interrupFan2,FALLING);
}

void loop() {
  delay(2000);
  printFanDetails();  
}

void printFanDetails() {
    Serial.print(getFanRPM1());
    Serial.print(F("\t"));
    Serial.print(getFanRPM2());
    Serial.println();
}

int getFanRPM1() {
  double ret = fan1RotationCount /2L *1000L * 60L / ( millis() - fan1TimeStart );
  fan1RotationCount = 0;
  fan1TimeStart = millis();
  return  ret;
}

int getFanRPM2() {
  double ret = fan2RotationCount /2L * 1000L * 60L / ( millis() - fan2TimeStart );
  fan2RotationCount = 0;
  fan2TimeStart = millis();
  return  ret;
}

the full code is in GitHub
https://github.com/kiwisincebirth/iMacG5/tree/FanTrial/SourceCode/iMac_i5_Rev10

SMC BOARD

With the RPM feedback from fans tested, and utilising MacTesters confirmed PWM fan controller. I have committed to producing a SMC board with these features (no more LM317). My main task left is to get the WTV020 sound module to work, and integrate and test with relay (input side), and PAM amplifier.

So the redesign of the SMC board continues; Size is now 85mm x 65mm; I have had to move a lot of pins to make use of the three available Interrupt pins. I have been working on the GND plane, and have separated the audio section from the rest of the fan control and microprocessor.

Kiwi

NOTE: The diagrams were removed See here for final diagrams http://www.tonymacx86.com/imac-mods/107859-kiwis-next-project-imac-g5-27.html#post985797

Why did you change the audio amp? You will loose the available area below it
Mainly because it is smaller, it doesn’t have the large components of the original. It will need to be mounted on standoffs as before, as the relay is underneath it. I am also considering mounting it on the underside of the PCB, it is only about 4mm thick.

I've enhanced your .h file to allow the adjustment of the PWM frequency for all the required PWM pins.
The PWM Frequency Library is hosted on GitHub, it has been enhanced to support UNO timers, not that it matters for this application.
 
Hi Kiwi,

how absolutely amazing job !!!:headbang::headbang::headbang:!!! I just found out that you had to find a way to control the brightness via Mac OS X ....

that's exactly what I need for my power iMac mods !!! this will concern my last last last step because it will control not only indispensable function for my use: brightness and sleep LED control , and the start chimes....
kiwi thank you for this hard job and your contribution !!!

cordialy

spong_jojo
Your welcome. There is a possibility of adapting this to a G4 build, but I don't know what the real requirements are? Have created a different thread over here to co-ordinate the effort.

http://www.tonymacx86.com/imac-mods/153762-imac-smc-controller-g5-g4.html#post961086
 
Hi Kiwi

This PCB layout looks incredibly good! :thumbup:

With the RPM feedback from fans tested, and utilising MacTesters confirmed PWM fan controller

Just to let you know: I'm just doing some additional investigations on how the Apple fans work:
- PWM frequency is 100Hz. I did expect, that they are driven in PWM mode, but not with such a low frequency.
- The tach signals produce a nice, clean 3.3V square wave. It seems, that the tach signal is pulled up to 3.3V through the logic board. The frequencies are: CPU 50 - 186Hz, HD 83 - 215Hz, Case ? - 168Hz.

So I've decided to change the fan PWM frequency to 123Hz. Advantages:
- No switching noise audible as well
- Closer to the original Apple spec
- Power transistor runs a b it cooler (will most likely use a BD438)
- The touch sensor readings are much more stable now and it seems that the touch sensors are usable now. fingers crossed...

The following changes were done in the PWM controller:
- replaced the 220R pull up resistor with a 1K, because it ran out of spec (0.66W). Still produces a clean 12V square wave.
- Added a 4.7uF cap across the fan, in parallel with the flyback diode. The fan runs smoother with it and the waveform looks much better.

To allow 123Hz PWM frequency, I had to clean out a bug inside the .h file (see comment at the top):
Code:
//
// -----------------------
// PWM FREQUENCY PRESCALER
// -----------------------
// Written by Kiwisincebirth 2014
// Revised by MacTester57 to allow correct PWM frequencies (confirmed with oscilloscope). January 2015
// - prescale variable: replaced uint8_t with uint16_t data type (fixes bug, which did not allow frequencies < 492Hz)
// - mode variable: replaced hex format with binary to make it more readable, if compared with bit tables in the 32U4 manual
// - added comments

/**
 * Arduino Leonardo AtMega 32u4 specific
 * Sets the Prescaler (Divisor) for a given PWM pin. The resulting frequency
 * is equal to the base frequency divided by the given divisor:
 *   - Base frequencies:
 *      o The base frequency for pins 3, and 11 is 64,500 Hz.
 *      o The base frequency for pins 5, 9, and 10 is 31,250 Hz.
 *      o The base frequency for pins 6 and 13 is 125,000 Hz.
 *   - Divisors:
 *      o The divisors available on pins 3, 5, 9, 10 and 11 are: 1, 8, 64, 256, and 1024.
 *      o The divisors available on pins 6 and 13 are all powers of two between 1 and 16384
 *
 * PWM frequencies are tied together in pairs of pins. If one in a
 * pair is changed, the other is also changed to match:
 *   - Pins 3 and 11 are paired on timer0 (8bit)
 *   - Pins 9 and 10 are paired on timer1 (16bit)
 *   - Pins 6 and 13 are paired on timer4 (10bit)
 *   - Pins 5 is exclusivly on timer3 (16bit)
 *
 * Note: Pins 3 and 11 operate on Timer 0 changes on this pins will
 * affect the user of the main time millis() functions
 */
void setPWMPrescaler(uint8_t pin, uint16_t prescale) {
  if (pin == 3 || pin == 11) {  // Pin3 tested, OK, but millis() is affected!! (see 32U4 manual page 105-106)
    byte mode;
    switch (prescale) {
      case 1: mode = 0b001; break; //CK (31.5kHz)
      case 8: mode = 0b010; break; //CK/8
      case 64: mode = 0b011; break; //CK/64
      case 256: mode = 0b100; break; //CK/256 (123Hz)
      case 1024: mode = 0b101; break; //CK/1024
      default: return;
    }
    TCCR0B = TCCR0B & 0b11111000 | mode;  // timer0 (8bit)
  }

  if (pin == 5 || pin == 9 || pin == 10) { //(see 32U4 manual page 133)
    byte mode;
    switch (prescale) {
      case 1: mode = 0b001; break; //CK (31.5kHz)
      case 8: mode = 0b010; break; //CK/8
      case 64: mode = 0b011; break; //CK/64
      case 256: mode = 0b100; break; //CK/256 (123Hz)
      case 1024: mode = 0b101; break; //CK/1024
      default: return;
    }
    if (pin == 9 || pin == 10) {  // Pin 5, 9 & 10 tested, OK
      TCCR1B = TCCR1B & 0b11111000 | mode;  // timer1 (16bit)
    } else {
      TCCR3B = TCCR3B & 0b11111000 | mode;  // timer3 (16bit)
    }
  }

  if (pin == 6 || pin == 13) {  // Pin 6 tested, with oscilloscope! (see 32U4 manual pages 165-166)
    byte mode;
    switch (prescale) {
      case 1: mode = 0b0001; break; //CK (31.5kHz)
      case 2: mode = 0b0010; break; //CK/2
      case 4: mode = 0b0011; break; //CK/4
      case 8: mode = 0b0100; break; //CK/8
      case 16: mode = 0b0101; break; //CK/16
      case 32: mode = 0b0110; break; //CK/32
      case 64: mode = 0b0111; break; //CK/64 (492Hz)
      case 128: mode = 0b1000; break; //CK/128
      case 256: mode = 0b1001; break; //CK/256 (123Hz)
      case 512: mode = 0b1010; break; //CK/512
      case 1024: mode = 0b1011; break; //CK/1024
      case 2048: mode = 0b1100; break; //CK/2048
      case 4096: mode = 0b1101; break; //CK/4096
      case 8192: mode = 0b1110; break; //CK/8192
      case 16384: mode = 0b1111; break; //CK/16384
      default: return;
    }
    TCCR4B = TCCR4B & 0b11110000 | mode;  // timer4 (10bit)
  }
}

MacTester

BTW: I'm doing some tests with Eagle...
 
You two are accomplishing some great things here.

A plug n play G5 mod solution is a fantastic idea.

Keep up the excellent work!


Cheers!
 
You two are accomplishing some great things here.

Thanks, ersterhernd. Such a "from one end of the world to the other cooperation" is just fun! And of course I'm hoping, that the result will be useful.

Kiwi, some more infos:
- I've tested your tach interrupt solution with three fans. works fine! :thumbup: I don't know why it did not work during my last tests. One minor thing: some arriving serial data are lost - deactivating the inverter during display sleep is not reliable anymore. I've read that this could happen, if interrupts are used: http://arduino.cc/en/pmwiki.php?n=Reference/AttachInterrupt

Note

Inside the attached function, delay() won't work and the value returned by millis() will not increment. Serial data received while in the function may be lost. You should declare as volatile any variables that you modify within the attached function. See the section on ISRs below for more information.

-> your thoughts?

- I can confirm, that the touch sensors only work properly, if the fans are driven with 123Hz PWM frequency. Otherwise the readings are unstable.

- If I read correctly (in your eagle screenshot), you plan to use pin 10 for the inverter. This does not work, because we will probably use different PWM frequencies for the fans and the inverter. So I've changed the inverter back to pin 5 (Timer 3). Fans: pins 6 (Timer 4), pin 9 & 10 (Timer 1). I've tested all the frequencies with the scope: inverter = 31.5kHz, fans 123Hz.

MacTester
 
If I read correctly (in your eagle screenshot), you plan to use pin 10 for the inverter. This does not work, because we will probably use different PWM frequencies for the fans and the inverter. So I've changed the inverter back to pin 5 (Timer 3). Fans: pins 6 (Timer 4), pin 9 & 10 (Timer 1). I've tested all the frequencies with the scope: inverter = 31.5kHz, fans 123Hz.
:banghead:

Thanks or the heads-up, sorry I can't do a detailed reply (time), have made the change to the board. Have attached the full schematic. Hope it helps

The following changes were done in the PWM controller:
You will also note I added a pull-up resistor to the input of the PWM controller, so that when the arduino is booting up you get fans turned full on. This I think is important for obvious reasons, but also alerts you to when you just flashed the wrong Arduino with the "Hello World" sketch.

deactivating the inverter during display sleep is not reliable anymore
The interrupt handlers are very short, and serial baud rate is very low, so this shouldn't be an issue. One thing I found was during Arduino development on my iMac, the Brightness app would detect the wrong USB port (multiple Arduinos attached), and screen would not wake up. I know this because as soon as I removed my second Arduino board, as the screen would immediately wake up again.

Could this be the issue? If not will look a bit more into it.

Kiwi

NOTE: The diagrams were removed See here for final diagrams http://www.tonymacx86.com/imac-mods/107859-kiwis-next-project-imac-g5-27.html#post985797
 
To allow 123Hz PWM frequency, I had to clean out a bug inside the .h file (see comment at the top):

MacTester

BTW: I'm doing some tests with Eagle...
Thanks for fixing the bug. I have included it in my code. I also wrote an example sketch for the library, that use the interrupt frequency counting to set and test the various frequencies. You just need to connect each PWM pin in turn to the interrupt pin, so that can work. It is in my github account.

You two are accomplishing some great things here. A plug n play G5 mod solution is a fantastic idea. Keep up the excellent work! Cheers!
Thanks, Yes its getting there.

Kiwi
 
Hi Kiwi

You will also note I added a pull-up resistor to the input of the PWM controller, so that when the arduino is booting up you get fans turned full on

Confirmed. But I've used 10K for R1 & R17 etc.

Could this be the issue? If not will look a bit more into it.

No. I've tested on the Cube with only one Arduino (on a breadboard) connected.

Thanks for fixing the bug. I have included it in my code.

Thanks.

Different topics:
- I would add a 100nF decoupling cap for the Arduino
- What's the reason for R9?
- Your inverter circuit could deliver more than 3.3V (depending on the inverter input resistance). I'm using a pullup to 3.3V. (see pic, signal inverted in software, no pulldown resistor in schematic)
inverter.jpeg

http://www.mikrocontroller.net/articles/Pegelwandler

- on your B2 PCB layout a trace from the power transistor to the PWM pin of Fan 3 header is missing?
-The fan 1 cable will not be long enough in a 17" model. (pic)
20150118-1184122.jpg

- A 3pin connector for a Servo (D0, 5V, GND) could be useful
- The new chime module is not yet wired. Relay looks good.
- could a voltage divider (or pot) for the chime volume adjustment be useful?

Thanks for all your effort!

MacTester
 
Status
Not open for further replies.
Back
Top