Load Control 5

The hardware was working fine. Each night, I'd remove the Arduino from the system so that I could noodle around with it in the IDE (development software). Once the Nano that I'd ordered had arrived, I'd put it into the production system and have the Duemilnove for testing and other possible projects.

One small problem that I had noticed was that with the increased sensitivity the new mouse provided, the Variac was going nuts when I ran the washing machine. The washer is a horizontal-axis unit, it agitates by running the drum one direction for a minute or so, then stops for a few seconds, then runs the drum in the opposite direction, repeating this cycle over and over. The Variac would frantically turn up and down in response to these cycles, and was really getting on my nerves. The controller would even try to adjust the dump power in response to water and clothes tumbling in the washer drum, the loading and unloading of the washer motor was evident in the wattmeter disc motion.

I would be fine if it was a bit more relaxed during washing, and so I needed to now decrease the mouse sensitivity. That's easy in software. I chose a digital port as an input, and altered the program so that when a voltage was applied to the port, the program would hold off doing anything until the mouse data was one integer higher than the minimum threshold (from anything greater than zero to anything greater than one). This allowed small variation in current to go through without activating the Variac, but larger load changes would make the system react pretty much as normal.

Because having an electromechanical device (the Variac) as a integral part of the power control circuit was obviously causing some noise and concerns about wear-and-tear on the bearings, gears, brushes, etc, a solid-state solution would be much more preferable. It didn't take much programming to insert some code to provide a PWM output on one of digital ports that could ultimately be used to control a triac device. Once this triac was installed, instantaneous response to current changes would be possible, and rather then being a concern, it would be a desirable feature.

The triac control takes the movement data from the mouse and keeps a running total of the values, from 0 to 255, turning that into the PWM signal on the Arduino output pin. This total is calculated not only from the simple movement of the mouse, but is a product of the speed at which the meter disc is spinning. When the disc spins in the "down" direction, the negative value numbers generated in the mouse data are added to the total, bringing it down (a negative number and a positive number added together is the same as subtracting one positive number from another).

Since this project is taking on a modular aspect, I left the code in the program, and simply put an amber LED on the output pin for now. Once it's all built and installed in the wattmeter body, I'll do some testing and prototyping on the triac drivers. Obviously, I'll leave room for the small circuit board that will be needed to integrate the triac driver into the whole.

So, now for some code. This is the program as it's running right now.

#include <ps2.h>

// an arduino sketch to interface with a ps/2 mouse and a hacked watthour meter
// Raises variac when mouse is moved forward, lowers when moved back
// Also provides PWM output for eventually driving a traic device

// Pins 8 - 9 are the optoisolated variac controller pins
// Pin2 is the low sensitivity switch input.
const int raisePin = 8, lowerPin = 9, switchPin = 2;
int raiseLower = 0,  switchState = 0,  triac = 0,  disc_velocity = 0;

// Pin 6 is the clock, pin 5 is data
PS2 mouse(6, 5);

// initialize the mouse. Reset it, and place it into remote
// mode so we can get the encoder data on demand
void mouse_init() {
  mouse.write(0xff);   // reset
  mouse.read();        // ack byte
  mouse.read();        // blank */
  mouse.read();        // blank */
  mouse.write(0xf0);   // remote mode
  mouse.read();        // ack
  delayMicroseconds(100);
}

void controller_init() {
  pinMode(raisePin, OUTPUT);      // Green LED indicator
  pinMode(lowerPin, OUTPUT);      // Red LED indicator
  pinMode(switchPin, INPUT);     // initialize High sensitivity pin as an input:
  pinMode(10, OUTPUT);            // pin 10 feeds the triac controller chip
}

void setup() {
//  Serial.begin(9600);  // Serial connection commented out until needed for testing
  mouse_init();
  controller_init();
}

void controller_loop() {
  if (raiseLower > 0) {            // Lower
    digitalWrite(lowerPin, HIGH);
    digitalWrite(raisePin, LOW);
  } else if (raiseLower < 0) {     // Raise
    digitalWrite(lowerPin, LOW);
    digitalWrite(raisePin, HIGH);
  } else {                         // Do nothing
    digitalWrite(lowerPin, LOW);
    digitalWrite(raisePin, LOW);
  }
}

void triac_loop() {
  // set the output of pin 10:
  analogWrite(10, triac);
//  triac = triac + disc_velocity;     // change the output for next time through the loop:
  triac = triac - raiseLower;        // change the output for next time through the loop:
  triac = constrain(triac, 0, 255);  // Don't loop back to the beginning or end
  }

// get a reading from the mouse and report it back to the host via the serial line.
 
void loop() {
  char mstat;
  char mx;
  char my;
  
  switchState = digitalRead(switchPin);  // Low sensitivity

  // get a reading from the mouse
  mouse.write(0xeb);  // give me data!
  mouse.read();      // ignore ack
  mstat = mouse.read();
  mx = mouse.read();
  my = mouse.read();

  disc_velocity = -my;
  
 if (switchState == HIGH){ // Low sensitivity
    if (my == 0){
      raiseLower = 0;
    } else if (my < -1) {
      raiseLower = -1;
    } else if (my > 1){
      raiseLower = 1;
    }  
  }
  else {            // High sensitivity
     if (my == 0){
      raiseLower = 0;
    } else if (my < 0) {
      raiseLower = -1;
    } else if (my > 0){
      raiseLower = 1;
    }  
  }
/*    // Serial connection commented out until needed for testing  
  // send the data back up
  Serial.print("Y=");
  Serial.print(my, DEC);
  Serial.print("\tr/l=");
  Serial.print(raiseLower, DEC);
  Serial.print("\ttriac=");
  Serial.print(triac, DEC);
  Serial.println();
*/    
  controller_loop();
  triac_loop();
 }

A good C programmer would probably bury his face in his hands after looking at this code, but it compiles and works, what more do I need?

That's about it for this part of the project, but there's more, once I got started, I discovered several other interesting things I could include as "add-ons" to make this even more functional.

 

 

 

 

Original material ©1996-2024 Mr. Sharkey | All rights reserved

If you see kay spam
Bombs Away