Week 12 - Networking and Communications


Posted by Jordan Kennedy on December 6, 2017

This week I would like my DC Motor Boards to communicate.

MotorBoards

During Output Device week I created two DC motor boards.

I created both Neil’s DC Motor board and a modified motor board with a button.

My goal is to press the button on my modified DC Motor circuit (Master) and a motor connected to Neil’s DC Motor board (slave) to change speed.

MBConnected

As I press the button on my modified DC Motor Board, the other DC Motor board changes speed.

It was surprisinly slow to communicate between the two boards, but it did communicate.

MBConnectedSpeaking

Master Board (Input) Code

//
//
// hello.H-bridge.44.DC.c
//
// H-bridge DC motor hello-world
//
// Neil Gershenfeld
// 11/18/12
//
// (c) Massachusetts Institute of Technology 2012
// This work may be reproduced, modified, distributed,
// performed, and displayed for any purpose. Copyright is
// retained and must be preserved. The work is provided
// as is; no warranty is provided, and users accept all 
// liability.
//

#include <avr/io.h>

#include <util/delay.h>


#define output(directions,pin) (directions |= pin) // set port direction for output

#define input(directions,pin) (directions &= (~pin)) // set port direction for input

#define set(port,pin) (port |= pin) // set port pin

#define clear(port,pin) (port &= (~pin)) // clear port pin

#define pin_test(pins,pin) (pins & pin) // test for port pin

#define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set


#define on_delay() _delay_us(10) // PWM on time

#define fast_off_delay() _delay_us(1) // PWM fast off time

#define medium_off_delay() _delay_us(3) // PWM medium off time

#define slow_off_delay() _delay_us(5) // PWM slow off time

#define long_delay() _delay_us(1000000) // Long Delay for button hold

#define PWM_count 20000 // number of PWM cycles

#define cycle_count 10 // number of speed cycles


#define bridge_port PORTA // H-bridge port

#define bridge_pin PINA // H-bridge pin

#define bridge_direction DDRA // H-bridge direction

#define IN1 (1 << PA3) // IN1

#define IN2 (1 << PA2) // IN2

#define BUTTON (1 << PA7) // BUTTON

#define LOWER (1 << PA4) // LOWER

#define HIGHER (1 << PA6) // HIGHER


#define lowSpeed 0

#define midSpeed 1

#define highSpeed 2

#define highestSpeed 3


int motorDelay()
{
  int err = 0;
  int lowerState = (bridge_pin &= LOWER) >> PA4;
  int higherState = (bridge_pin &= HIGHER) >> PA6;
  int selection = 2*higherState + lowerState;
  switch(selection)
  {
    case 0: 
      slow_off_delay(); 
      break;
    case 1: 
      medium_off_delay(); 
      break;
    case 2: 
      fast_off_delay(); 
      break;
    default: 
      break;
  }
  return err;
}

int main(void) 
{
   //
   // main
   //
   static uint16_t count;
   static uint8_t cycle;
   //
   // set clock divider to /1
   //
   CLKPR = (1 << CLKPCE);
   CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
   //
   // initialize H-bridge pins
   //
   clear(bridge_port, IN1);
   output(bridge_direction, IN1);
   clear(bridge_port, IN2);
   output(bridge_direction, IN2);

   //
   // initialize Comm pins
   //
   clear(bridge_port, LOWER);
   input(bridge_direction, LOWER);
   clear(bridge_port, HIGHER);
   input(bridge_direction, HIGHER);

   //
   // initialize button pin
   //
   clear(bridge_port, BUTTON);
   input(bridge_direction, BUTTON);
   
   // for now just spin forward
   clear(bridge_port, IN1);
   set(bridge_port, IN2);
   // start with motor in low speed
   int speed = 0;

   // set button state
   int buttonState = 1;
   
   //
   // main loop
   //
   while (1) 
   {
      set(bridge_port, IN2);
      on_delay();
      clear(bridge_port, IN2);
      motorDelay();
   }
}

Slave Board (Output) Code

//
//
// hello.H-bridge.44.DC.c
//
// H-bridge DC motor hello-world
//
// Neil Gershenfeld
// 11/18/12
//
// (c) Massachusetts Institute of Technology 2012
// This work may be reproduced, modified, distributed,
// performed, and displayed for any purpose. Copyright is
// retained and must be preserved. The work is provided
// as is; no warranty is provided, and users accept all 
// liability.
//

#include <avr/io.h>

#include <util/delay.h>


#define output(directions,pin) (directions |= pin) // set port direction for output

#define input(directions,pin) (directions &= (~pin)) // set port direction for input

#define set(port,pin) (port |= pin) // set port pin

#define clear(port,pin) (port &= (~pin)) // clear port pin

#define pin_test(pins,pin) (pins & pin) // test for port pin

#define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set


#define on_delay() _delay_us(4) // PWM on time

#define fast_off_delay() _delay_us(1) // PWM fast off time

#define medium_off_delay() _delay_us(3) // PWM medium off time

#define slow_off_delay() _delay_us(5) // PWM slow off time

#define long_delay() _delay_us(1000000) // Long Delay for button hold

#define PWM_count 20000 // number of PWM cycles

#define cycle_count 10 // number of speed cycles


#define bridge_port PORTA // H-bridge port

#define bridge_pin PINA // H-bridge pin

#define bridge_direction DDRA // H-bridge direction

#define IN1 (1 << PA3) // IN1

#define IN2 (1 << PA2) // IN2

#define BUTTON (1 << PA7) // BUTTON

#define LOWER (1 << PA4) // LOWER

#define HIGHER (1 << PA6) // HIGHER


#define lowSpeed 0

#define midSpeed 1

#define highSpeed 2

#define highestSpeed 3


int motorDelay(int selection)
{
  int err = 0;
  switch(selection)
  {
    case lowSpeed: 
      clear(bridge_port, LOWER);
      clear(bridge_port, HIGHER);
      slow_off_delay(); 
      break;
    case midSpeed: 
      medium_off_delay(); 
      set(bridge_port, LOWER);
      clear(bridge_port, HIGHER);
      break;
    case highSpeed: 
      clear(bridge_port, LOWER);
      set(bridge_port, HIGHER);
      fast_off_delay(); 
      break;
    case highestSpeed: 
      set(bridge_port, LOWER);
      set(bridge_port, HIGHER);
      break;
    default: err = 1; break;
  }
  return err;
}

int main(void) 
{
   //
   // main
   //
   static uint16_t count;
   static uint8_t cycle;
   //
   // set clock divider to /1
   //
   CLKPR = (1 << CLKPCE);
   CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
   //
   // initialize H-bridge pins
   //
   clear(bridge_port, IN1);
   output(bridge_direction, IN1);
   clear(bridge_port, IN2);
   output(bridge_direction, IN2);

   //
   // initialize Comm pins
   //
   clear(bridge_port, LOWER);
   output(bridge_direction, LOWER);
   clear(bridge_port, HIGHER);
   output(bridge_direction, HIGHER);

   //
   // initialize button pin
   //
   clear(bridge_port, BUTTON);
   input(bridge_direction, BUTTON);
   
   // for now just spin forward
   clear(bridge_port, IN1);
   set(bridge_port, IN2);
   // start with motor in low speed
   int speed = 0;

   // set button state
   int buttonState = 1;
   
   //
   // main loop
   //
   while (1) 
   {
      set(bridge_port, IN2);
      on_delay();
      clear(bridge_port, IN2);
      buttonState = (bridge_pin &= BUTTON) >> PA7;
      motorDelay(speed);
      
      if(buttonState == 0)
      {
        speed += 1;
        if (speed > highestSpeed)
        {
          speed = lowSpeed;
        }
        long_delay();
      }
      
   }
}