Arduino Tamagotchi Prototyping - Управление регистрацией прерываний - PullRequest
0 голосов
/ 19 октября 2018

Я на самом деле разрабатываю немного "Тамагочи".

  • Кнопка действия кормит "Тамагочи"
  • Переключатель наклона предназначен для сна "Тамагочи"

Я не понимаю, почему функция onChange() для датчика наклона Датчик не срабатывает.

Примечание: переключатель наклона установлен на A1 ( ATTiny85 Pin).

Rem: Вместо управления функцией onChange() с использованием analogRead() будет приветствоваться низкоуровневое управление с использованием сопоставления выводов и прерывания на порту A1 (например: if (!(PORTB & (1<<PB0)))

При этом код:

// STATE MACHINE
enum State_enum {ALIVE, HUNGRY, FEED, HAPPY, TIRED, SLEEPY, DEAD};
enum Sensors_enum {NONE, BUTTON, TILT, BOTH};

void state_machine_run(uint8_t sensors);
void isAlive();
boolean isHungry();
void isFeeding();
void isHappy();
boolean isTired();
void isSleeping();
boolean isDead();
void hasDie();
uint8_t readSensors();

uint8_t state = ALIVE;

// BOT PROPERTIES
long feed=10000;
long sleep=10000;
boolean hasEat = true;
boolean isItDead = false;
boolean hasSleep = true;
boolean happy = false;

/* RBG LED PROPERTIES */
const byte PIN_LED_R = 0; // connect Red LED to pin 0
const byte PIN_LED_G = A2;  // connect Red LED to pin A2
const byte PIN_LED_B = A3;  // connect Red LED to pin A3
/* Color Const Settings  */
const byte COLOR_WHITE = 0b111;
const byte COLOR_BLACK = 0b000;
const byte COLOR_RED = 0b100;
const byte COLOR_GREEN = 0b010;
const byte COLOR_BLUE = 0b001;
const byte COLOR_YELLOW = 0b110;
const byte COLOR_CYAN = 0b011;
const byte COLOR_PURPLE = 0b101;

/* RGB LED CLASS */
class RGBLed {
  // Constructor
  int PIN_LED_R;
  int PIN_LED_G;
  int PIN_LED_B;

  /* Color Const Settings  */
  const byte COLOR_BLACK = 0b000;
  const byte COLOR_RED = 0b100;
  const byte COLOR_GREEN = 0b010;
  const byte COLOR_BLUE = 0b001;

  public :
  RGBLed(int redLedPin, int greenLedPin, int blueLedPin) {
    PIN_LED_R = redLedPin;
    PIN_LED_G = greenLedPin;
    PIN_LED_B = blueLedPin;
    pinMode(PIN_LED_R, OUTPUT);
    pinMode(PIN_LED_G, OUTPUT);
    pinMode(PIN_LED_B, OUTPUT);
    digitalWrite(PIN_LED_R, LOW);
    digitalWrite(PIN_LED_G, LOW);
    digitalWrite(PIN_LED_B, LOW);
  }

  void displayColor(byte color) {
  digitalWrite(PIN_LED_R, !bitRead(color, 2));
  digitalWrite(PIN_LED_G, !bitRead(color, 1));
  digitalWrite(PIN_LED_B, !bitRead(color, 0));
  }

  /* Sequence Effect */
  void isBlinking(byte color) {
    for (int count = 0; count < 10; count++) {
      this->displayColor(color);
      delay(50);
      this->displayColor(COLOR_BLACK);
      delay(50);
    }
  }
};


/* BUTTON PROPERTIES */
const byte PIN_BUTTON = 1;  // connect Button to pin 1
/* BUTTON CLASS */
class Button {

  // Constructor
  int buttonPin;
  int lastButtonState;
  int currentButtonState;
  boolean isButtonPressed = false;
  byte count = 0;

  public :
  Button(int pin) {
    buttonPin = pin;
    pinMode(buttonPin, INPUT);
    currentButtonState = digitalRead(buttonPin);
  }

  boolean onChange() {
    // Read the current Switch state on PIN #1
    currentButtonState = digitalRead(buttonPin);

    // Compare current state with previous state
    if(currentButtonState != lastButtonState) {
      if(currentButtonState == LOW) {
        isButtonPressed = true;
        count++;
      } else {
        isButtonPressed = false;
        count=0;
      }
      lastButtonState = currentButtonState;

    }
    delay(100);
    return isButtonPressed;
  }

  byte getCount() {
    return count;
  }
};

/* MOTION DETECTOR PROPERTIES */
const byte PIN_MOTION_DETECTOR = A1;
/* MOTION DETECTOR CLASS */
class MotionDetector {
  int motionDetectorPin;
  int motionDetectorValue = 0;
  boolean motionDetectorStatus = false;

  // Constructor
  public:
  MotionDetector(int pin) {
    motionDetectorPin = pin;
    pinMode(motionDetectorPin, INPUT);
    //motionDetectorValue=analogRead(motionDetectorPin); // For calibration ...
  }

  // Creature has moved !
  //boolean onChange(int motionValue) {
  boolean onChange() {
    //boolean motionDetectorStatus = false;
    //analogRead(motionDetectorPin)
    //motionDetectorValue = motionValue;    
    if (analogRead(motionDetectorPin) > 0) {
      motionDetectorStatus = true;
    } else {
      motionDetectorStatus = false;
    }
    return motionDetectorStatus;
  }
};

/* Create Instance of bOop components */
Button myButton(PIN_BUTTON);
RGBLed myRGBLed(PIN_LED_R,PIN_LED_G,PIN_LED_B);
MotionDetector myMotionDetector(PIN_MOTION_DETECTOR);

void setup(){
  myRGBLed.isBlinking(COLOR_BLUE);
}

void loop(){
  state_machine_run(readSensors()); 
  delay(10);
}

void state_machine_run(uint8_t sensors) 
{
  switch(state)
  {
    case ALIVE:
      if(sensors == NONE) {
        if (!isItDead) isAlive();
        if (isHungry()) {
          state = HUNGRY;
          //myRGBLed.displayColor(COLOR_RED);
        } else if(isTired()) {
          state = TIRED;
          //myRGBLed.displayColor(COLOR_YELLOW);
        } else {
          state = HAPPY;
        }
      }

      else if(sensors == BUTTON) {
        state = FEED;
      }

      else if(sensors == TILT) {
        state = SLEEPY;
      }

      else {
        state = ALIVE;
      }
      break;

    case HUNGRY:
      if(sensors == BUTTON){
        state = FEED;
      } else {
        feed--;
        if (isDead()){
          state = DEAD;
        } else {
          state = HUNGRY;
        }
      }
      break; 

    case FEED:
      if(sensors == BUTTON) {
        isFeeding();
        state = FEED;
      } else {
        state = HAPPY;
      }
    break;

    case HAPPY:
      if(sensors == NONE) {
        isHappy();
        state = ALIVE;
      }
    break;

    case TIRED:
      if(sensors == TILT) {
        state = SLEEPY;
      } else {
        sleep--;
        if (isDead()){
          state = DEAD;
        } else {
          state = TIRED;
        }
      }
      break;

    case SLEEPY:
      if(sensors == TILT) {
        isSleeping();
        state = SLEEPY; 
      } else {
        state = HAPPY;
      }
      break;

    case DEAD:
      hasDie();
      state = DEAD;
      break;
  }
}

void isAlive() {
  feed--;
  sleep--;
  myRGBLed.displayColor(COLOR_BLUE);
}

boolean isDead() {
  if (feed <0 || sleep <0) {
    isItDead = true;
  } else {
    isItDead = false;
  }
  return isItDead;
}

boolean isHungry() {
  if (feed>1000) {
    hasEat = true;
    state = ALIVE;
  } else {
    hasEat = false;
    myRGBLed.isBlinking(COLOR_RED);
    state = HUNGRY;
  }
  return hasEat;
}

boolean isTired() {
  if(sleep>1000) {
    hasSleep = true;
    state = ALIVE;
  } else {
    hasSleep = false;
    myRGBLed.isBlinking(COLOR_YELLOW);
    state = TIRED;
  }
  return hasSleep;
}

void isFeeding() {
  feed=feed+25000;
  myRGBLed.displayColor(COLOR_GREEN);
}

void isHappy() {
  myRGBLed.isBlinking(COLOR_CYAN);
}
 long randNumber;

void isSleeping() {
  sleep=sleep+7000;
  if(random(100)==3){
    myRGBLed.displayColor(COLOR_PURPLE);
  } else {
    myRGBLed.displayColor(COLOR_WHITE);
  }
}

void hasDie() {
  myRGBLed.displayColor(COLOR_BLACK);
}

uint8_t readSensors()
{
  //int motionDetectorCurrentValue = analogRead(PIN_MOTION_DETECTOR);

//if (myMotionDetector.onChange(analogRead(PIN_MOTION_DETECTOR))) {
  if (myButton.onChange()) {
    return BUTTON;
  } else if (myMotionDetector.onChange()) {
    return TILT;
  } else {
    return NONE;
  }
}
...