2014年10月19日 星期日

[Raspberry Pi][Arduino] Raspberry Pi control bar graph LED throught arduino



enter image description here

Study the following two article

1. [Raspberry Pi][Arduino] Raspberry pi connect to arduino by using I2C
2. [Arduino] Using 74HC595 to control bar graph LED

Arduino Code :

#include <Wire.h>
#define SLAVE_ADDRESS 0x04

int number = 0;
int state = 0;
int LED_Num = 0;

//Pin connected to ST_CP of 74HC595
int latchPin = 8;

//Pin connected to SH_CP of 74HC595
int clockPin = 12;

////Pin connected to DS of 74HC595
int dataPin = 11;
double temp;

void setup() {
    Serial.begin(9600); // send and receive at 9600 baud

    //set pins to output so you can control the shift register
    pinMode(latchPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    pinMode(dataPin, OUTPUT);

    // initialize i2c as slave
    Wire.begin(SLAVE_ADDRESS);

    // define callbacks for i2c communication
    Wire.onReceive(receiveData);
    Wire.onRequest(sendData);
}



void loop() {
    delay(100);
}



// callback for received data

void receiveData(int byteCount){

 while(Wire.available()) {



  number = Wire.read();



  switch (number) {
    case 0:
      LED_Num = number;
      break;

    case 1:
      LED_Num = number;
      break;

    case 2:
      LED_Num = number;
      break;

    case 3:
      LED_Num = number;
      break;

    case 4:
      LED_Num = number;
      break;

    case 5:
      LED_Num = number;
      break;

    case 6:
      LED_Num = number;
      break;

    case 7:
      LED_Num = number;
      break;

    case 8:
      LED_Num = number;
      break;

    case 9:
      LED_Num = number;
      break;

    case 10:
      LED_Num = number;
      break;

    default:
      // if nothing else matches, do the default
      // default is optional
      break;
  }

    // digitalWrite(latchPin, LOW);
    // shift out the bits:
    // shiftOut(dataPin, clockPin, MSBFIRST, (1 << LED_Num) - 1);
    // take the latch pin high so the LEDs will light up:
    // digitalWrite(latchPin, HIGH);


    int numberToDisplay  = 1 << (LED_Num - 1);
    byte high_Byte = highByte(numberToDisplay);
    byte low_Byte = lowByte(numberToDisplay);

    /* Debug message  Crtl+Shift+M */
    Serial.print("The binary of high_Byte is ");
    Serial.println(high_Byte, BIN);
    Serial.print("The binary of  low_Byte is ");
    Serial.println(low_Byte, BIN);

    // 送資料前要先把 latchPin 拉成低電位
    digitalWrite(latchPin, LOW);

    // 先送高位元組 (Hight Byte), 給離 Arduino 較遠的那顆 74HC595
    shiftOut(dataPin, clockPin, MSBFIRST, high_Byte);

    // 再送低位元組 (Low Byte), 給離 Arduino 較近的那顆 74HC595
    shiftOut(dataPin, clockPin, MSBFIRST, low_Byte);

    // 送完資料後要把 latchPin 拉回成高電位
    digitalWrite(latchPin, HIGH);
 }
}

// callback for sending data
void sendData(){
 Wire.write(number);

}

Raspberry Pi Part:

#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>

// The PiWeather board i2c address
#define ADDRESS 0x04

// The I2C bus: This is for V2 pi's. For V1 Model B you need i2c-0
static const char *devName = "/dev/i2c-1";

int main(int argc, char** argv) {

  if (argc == 1) {
    printf("Supply one or more commands to send to the Arduino\n");
    exit(1);
  }

  printf("I2C: Connecting\n");
  int file;

  if ((file = open(devName, O_RDWR)) < 0) {
    fprintf(stderr, "I2C: Failed to access %d\n", devName);
    exit(1);
  }

  printf("I2C: acquiring buss to 0x%x\n", ADDRESS);

  if (ioctl(file, I2C_SLAVE, ADDRESS) < 0) {
    fprintf(stderr, "I2C: Failed to acquire bus access/talk to slave 0x%x\n", ADDRESS);
    exit(1);
  }

  int arg;

  for (arg = 1; arg < argc; arg++) {
    int val;
    unsigned char cmd[16];

    if (0 == sscanf(argv[arg], "%d", &val)) {
      fprintf(stderr, "Invalid parameter %d \"%s\"\n", arg, argv[arg]);
      exit(1);
    }

    printf("Sending %d\n", val);

    cmd[0] = val;
    if (write(file, cmd, 1) == 1) {

      // As we are not talking to direct hardware but a microcontroller we
      // need to wait a short while so that it can respond.
      //
      // 1ms seems to be enough but it depends on what workload it has
      usleep(10000);

      char buf[1];
      if (read(file, buf, 1) == 1) {
    int temp = (int) buf[0];

    printf("Received %d\n", temp);
      }
    }

    // Now wait else you could crash the arduino by sending requests too fast
    usleep(10000);
  }

  close(file);
  return (EXIT_SUCCESS);
}


Execute :

pi@raspberrypi ~/test $ ./raspberry_to_arduino 1
I2C: Connecting
I2C: acquiring buss to 0x4
Sending 1
Received 1

Reference :
1. switch / case statements
2. Arduino 筆記 – Lab12 使用兩顆 74HC595 和三支腳位控制 16 顆 LED
3. 4.1Sending Debug Information from Arduino to Your Computer
4. Arduino Tutorial #3 - Shift Registers (74HC595)




Related Posts:

0 意見:

張貼留言