Difficulty using interrupts to recreate the spark socket in a dimmer switch[SOLVED]

Hello,
I was so bummed not to get my spark socket that I’ve decided to use my cores to control a dimmer switch.
First off: I’m virtually a noob to coding.

I have my dimmer circuit wired and operational using an arduino but when I try the same firmware on my core it doesn’t work. I’m using very simple code that doesn’t require any libraries, so I believe it should be compatible. Here is the basic code I have to control my dimmer with a potentiometer:

int sensorPin = D2;
int AC_pin = D1;           //Pin to MOC3020 - OptoTriac
byte dim = 0;
int sensorValue = 0;//Initial brightness level from 0 to 255, change as you like!

void setup() {
  Serial.begin(9600);
  pinMode(AC_pin, OUTPUT);
  attachInterrupt(D0, light, FALLING);//When arduino Pin 2 is FALLING from HIGH to LOW, run light procedure!
}

void light() {
  
    sensorValue = analogRead(sensorPin);
    dim = map(sensorValue, 0, 1023, 0, 255);
    //dim = Serial.read();
    if (dim < 1) {                  //Turn TRIAC completely OFF if dim is 0
      digitalWrite(AC_pin, LOW);
    }
    if (dim > 254) {                //Turn TRIAC completely ON if dim is 255
      digitalWrite(AC_pin, HIGH);
    }
  
  if (dim > 0 && dim < 255) {      //Dimming part, if dim is not 0 and not 255
    delayMicroseconds(27*(255-dim));
    digitalWrite(AC_pin, HIGH);
    delayMicroseconds(500);
    digitalWrite(AC_pin, LOW);
  }
}

void loop() {

}

When I had difficulty with that firmware I tried a simple interrupt test with a switch and a LED:

int pin = D1;
volatile int state = LOW;

void setup()
{
  pinMode(pin, OUTPUT);
  attachInterrupt(D0, blink, CHANGE);
}

void loop()
{
  digitalWrite(pin, state);
}

void blink()
{
  state = !state;
}

Again, works on the Arduino but not the core. I’m wondering if I’m naming the interrupt right. I know Arduino interrupt 0 is actually physical pin 2. Does the core have a similar difference in interrupt name and pin name?
Thanks for any help!

Micah
ps. Hey @zach and @Steph. It’s super exciting to see what the Spark Core has/is becoming!

Hello @miro87043

The second example seems to work just fine. Please note that the user application is run only when the Core has successfully connected to the cloud (breathing cyan).

In your example, you are connecting an analog sensor to D2 (which on the Spark Core is a digital pin). Pins A0 to A7 are analog pins. So, you may want to try connecting the sensor to one of those pins.

Also, the ADC on the Spark Core returns a 12bit value (0 - 4095). You’ll have to make changes in your mapping function accordingly.

Hope this helps!

Thanks @mohit!
It took a bit of messing around, but I got it!
I first switched my sensor to an appropriate analog pin, but it still didn’t work. I then switched the interrupt to an analog pin as well and it worked. I didn’t know that mattered.

Anyhow, now that I have control of my dimmer with the Spark Core I should be able to figure how to control it through the cloud.

Thanks again!!

Hi @miro87043, a couple comments after looking at your code:

int sensorPin = D2; should be int sensorPin = A0;

dim = map(sensorValue, 0, 1023, 0, 255); should be dim = map(sensorValue, 0, 4095, 0, 255); because the Spark Core has a 12-bit ADC vs. the 10-bit ADC of the Arduino.

I see you rolled your own variable frequency PWM… I’m not sure if you need that for timing reasons or can you just use the on-board PWM?

analogWrite(dim); this works with your D1 pin as defined already as an OUTPUT, will give you a 0-100% PWM output at 500Hz. This will take care of turning it completely on or off as well, however you may want to leave your OFF / ON code in there to add more margin to your OFF or ON states because potentiometers tend to be a little crusty at the ends and might not bring your analog input quite to the rails.

if (dim < 3) {  //Turn TRIAC completely OFF if dim is below 3
  analogWrite(0);
}
else if (dim > 252) {  //Turn TRIAC completely ON if dim above 252
  analogWrite(255);
}
else {
  analogWrite(dim);  //Set TRIAC to dim/255 duty cycle
}

@BDub Thanks!!
I did change the sensor to an analog pin as it needed and adjusted my map. After that it worked as I expected.
The reason I’m not using on board PWM is that I’m dimming an AC light. If the circuit isn’t chopped in sync with the AC supply (60 Hz) the light will flicker (so I’ve read).
Now I’m removing the potentiometer control and adding cloud control (slowly-I’m still very new at coding). I will need a manual dimmer but I’m not sure how to do that along side the cloud functionality. The potentiometer value becomes arbitrary once I expose a function. Any tips?

Ah, well your Spark Core is still going to be out of sync with your AC, even if your frequency is the matched. I would think if you are off by a few Hertz in frequency, because of the asynchronous timing you will see the “beat frequency” (your freq. - AC freq). However if you increase your frequency to a multiple higher than the frequency you are chopping, you will have a high beat frequency that will be imperceivable to the human eye.

It looks like you may be using the interrupt with a zero crossing detector? If so try this for your timing:

// 60Hz timing
digitalWrite(AC_pin, HIGH);      // turn triac ON
delayMicroseconds(65*(dim));     // delay for ON time (takes up to 
digitalWrite(AC_pin, LOW);       // turn triac OFF
delayMicroseconds(65*(255-dim)); // delay for OFF time

Also speed up your mapping:
dim = analogRead(sensorPin)/16; // instead of dim = map(sensorValue, 0, 4095, 0, 255);

:smile:

I am using zero cross detection, so there should not be an sync issues. Even if there’s a delay it’ll still chop the circuit at the same place in wave each time. In any case, it appears that way as there isn’t any flickering.

The timing you posted looks similar to what was in another firmware I tried. That and the one I have seem to work equally well. I also adjusted my mapping. Thanks for that tip!

Here’s my schematic so it’s more clear what I’m working with. I developed it using the Spark Socket source and these two sources: http://wiki.dxarts.washington.edu/groups/general/wiki/4dd69/AC_Dimmer_Circuit.html
http://www.instructables.com/id/Arduino-controlled-light-dimmer-The-circuit/?ALLSTEPS

Aha, well that explains your timing then… seems to be adjusted for 120Hz vs. 60Hz of mine. You will be getting a pulse on the Pos and Neg cycle with a bridge rectifier, i.e., 120Hz.

Looks like a lot of fun!

@miro87043 Do you happen to have the code for this integration? I would love to integrate my sparkcore with a dimmer switch and, if you haven’t do it yet, add the control through the cloud.
Thanks!

I moved 2 posts to an existing topic: Inmojo dimmer issues