//// VARS
byte CLK_pin = 8;
byte EN_pin = 9;
byte DIO_pin = 10;
byte LED = 13;
int ZeroOffset = 0; // To calibrate the compass, run in uncalibrated mode [Section 1],
// point the sensor due North, and record the value sensed.
// Enter that value here and then run in calibrated mode [Section 2]
int X_Data = 0;
int Y_Data = 0;
int angle, status;
float Delta, xPrime, yPrime;
int ledN = 2;
int ledNE = 3;
int ledE = 4;
int ledSE = 5;
int ledS = 6;
int ledSW = 7;
int ledW = 11;
int ledNW = 12;
int buttonState = 0;
int buttonPin = 13;
int COValue = 0;
int MethaneValue = 0;
int buttonPushCounter = 0; // counter for the number of button presses
int lastButtonState = 0;
//// FUNCTIONS
void selectLineOne(){ //puts the cursor at line 0 char 0.
Serial.print(0xFE, BYTE); //command flag
Serial.print(128, BYTE); //position
}
void selectLineTwo(){ //puts the cursor at line 0 char 0.
Serial.print(0xFE, BYTE); //command flag
Serial.print(192, BYTE); //position
}
void goTo(int position) { //position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0
if (position<16){
Serial.print(0xFE, BYTE); //command flag
Serial.print((position+128), BYTE); //position
}
else if (position<32){
Serial.print(0xFE, BYTE); //command flag
Serial.print((position+48+128), BYTE); //position
}
else {
goTo(0);
}
}
void clearLCD(){
Serial.print(0xFE, BYTE); //command flag
Serial.print(0x01, BYTE); //clear command.
}
void backlightOn(){ //turns on the backlight
Serial.print(0x7C, BYTE); //command flag for backlight stuff
Serial.print(157, BYTE); //light level.
}
void backlightOff(){ //turns off the backlight
Serial.print(0x7C, BYTE); //command flag for backlight stuff
Serial.print(128, BYTE); //light level for off.
}
void serCommand(){ //a general function to call the command flag for issuing all other commands
Serial.print(0xFE, BYTE);
}
void ShiftOut(int Value, int BitsCount) {
for(int i = BitsCount; i >= 0; i--) {
digitalWrite(CLK_pin, LOW);
if ((Value & 1 << i) == ( 1 << i)) {
digitalWrite(DIO_pin, HIGH);
//Serial.print("1");
}
else {
digitalWrite(DIO_pin, LOW);
//Serial.print("0");
}
digitalWrite(CLK_pin, HIGH);
delayMicroseconds(1);
}
}
int ShiftIn(int BitsCount) {
int ShiftIn_result;
ShiftIn_result = 0;
pinMode(DIO_pin, INPUT);
for(int i = BitsCount; i >= 0; i--) {
digitalWrite(CLK_pin, HIGH);
delayMicroseconds(1);
if (digitalRead(DIO_pin) == HIGH) {
ShiftIn_result = (ShiftIn_result << 1) + 1;
//Serial.print("x");
}
else {
ShiftIn_result = (ShiftIn_result << 1) + 0;
//Serial.print("_");
}
digitalWrite(CLK_pin, LOW);
delayMicroseconds(1);
}
//Serial.print(":");
// below is difficult to understand:
// if bit 11 is Set the value is negative
// the representation of negative values you
// have to add B11111000 in the upper Byte of
// the integer.
// see: http://en.wikipedia.org/wiki/Two%27s_complement
if ((ShiftIn_result & 1 << 11) == 1 << 11) {
ShiftIn_result = (B11111000 << 8) | ShiftIn_result;
}
return ShiftIn_result;
}
void HM55B_Reset() {
pinMode(DIO_pin, OUTPUT);
digitalWrite(EN_pin, LOW);
ShiftOut(B0000, 3);
digitalWrite(EN_pin, HIGH);
}
void HM55B_StartMeasurementCommand() {
pinMode(DIO_pin, OUTPUT);
digitalWrite(EN_pin, LOW);
ShiftOut(B1000, 3);
digitalWrite(EN_pin, HIGH);
}
int HM55B_ReadCommand() {
int result = 0;
pinMode(DIO_pin, OUTPUT);
digitalWrite(EN_pin, LOW);
ShiftOut(B1100, 3);
result = ShiftIn(3);
return result;
}
void setup() {
Serial.begin(9600);
backlightOn();
pinMode(EN_pin, OUTPUT);
pinMode(CLK_pin, OUTPUT);
pinMode(DIO_pin, INPUT);
HM55B_Reset();
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(buttonPin, INPUT);
}
void loop() {
HM55B_StartMeasurementCommand(); // necessary!!
delay(40); // the data is 40ms later ready
status = HM55B_ReadCommand(); // read data
X_Data = ShiftIn(11); // Field strength in X
Y_Data = ShiftIn(11); // and Y direction
digitalWrite(EN_pin, HIGH); // Deselect chip
// [Section 1: Simple Angle calculation]
// To determine the angle using the raw sensor data, we can simply calculate
// the Inverse Tangent of Y_Data/X_Data. Uncomment the following line and comment
// all of [Section 2]
// angle = (180 * (atan2(-1 * Y_Data , X_Data) / M_PI)); // angle is atan( -y/x) !!!
// [End Section 1]
// [Section 2: Offset-Compensated Angle Calculation]
// To better match the compass readings with well known values of true north,
// you can use the following calculations to rotate the value of the tangent
// before determining the angle. To do this, we first need to run the program
// with the code in [Section 1] uncommented and note the angle value when we
// point the sensor to true north. Enter the value recorded at the top of
// this program in the variable "ZeroOffset", comment the code in [Section 1],
// and uncomment the code below.
Delta = (ZeroOffset/180.0)*M_PI; // Calculate radians from degrees
xPrime = X_Data*cos(Delta) - Y_Data*sin(Delta); // Translate the X_Data value based on
// rotating the original angle by "Delta" rads.
yPrime = Y_Data*cos(Delta) + X_Data*sin(Delta); // Translate the Y_Data value based on
// rotating the original angle by "Delta" rads.
angle = (180 * (atan2(-1 * yPrime , xPrime) / M_PI)); // angle is still atan(-y/x)
// [End Section 2]
if (abs(angle) < 10) {
digitalWrite (LED, HIGH);
}
else {
digitalWrite (LED, LOW);
}
if(angle > -22.5 && angle < 22.5){
digitalWrite(ledN, HIGH);
digitalWrite(ledNE, LOW);
digitalWrite(ledE, LOW);
digitalWrite(ledSE, LOW);
digitalWrite(ledS, LOW);
digitalWrite(ledSW, LOW);
digitalWrite(ledW, LOW);
digitalWrite(ledNW, LOW);
//selectLineTwo();
//Serial.println('angle');
}
else if(angle > 22.5 && angle < 67.5){
digitalWrite(ledNE, HIGH);
digitalWrite(ledN, LOW);
digitalWrite(ledE, LOW);
digitalWrite(ledSE, LOW);
digitalWrite(ledS, LOW);
digitalWrite(ledSW, LOW);
digitalWrite(ledW, LOW);
digitalWrite(ledNW, LOW);
//selectLineTwo();
//Serial.println('angle');
}
else if(angle > 67.5 && angle< 112.5){
digitalWrite(ledE, HIGH);
digitalWrite(ledNE, LOW);
digitalWrite(ledN, LOW);
digitalWrite(ledSE, LOW);
digitalWrite(ledS, LOW);
digitalWrite(ledSW, LOW);
digitalWrite(ledW, LOW);
digitalWrite(ledNW, LOW);
//selectLineTwo();
//Serial.println('angle');
}
else if(angle > 112.5 && angle < 157.5){
digitalWrite(ledSE, HIGH);
digitalWrite(ledNE, LOW);
digitalWrite(ledE, LOW);
digitalWrite(ledN, LOW);
digitalWrite(ledS, LOW);
digitalWrite(ledSW, LOW);
digitalWrite(ledW, LOW);
digitalWrite(ledNW, LOW);
//selectLineTwo();
//Serial.println('angle');
}
else if(angle > 157.5 || angle < -157.5){
digitalWrite(ledS, HIGH);
digitalWrite(ledNE, LOW);
digitalWrite(ledE, LOW);
digitalWrite(ledSE, LOW);
digitalWrite(ledN, LOW);
digitalWrite(ledSW, LOW);
digitalWrite(ledW, LOW);
digitalWrite(ledNW, LOW);
//selectLineTwo();
//Serial.println('angle');
}
else if(angle < -22.5 && angle > -67.5){
digitalWrite(ledNW, HIGH);
digitalWrite(ledNE, LOW);
digitalWrite(ledE, LOW);
digitalWrite(ledSE, LOW);
digitalWrite(ledS, LOW);
digitalWrite(ledSW, LOW);
digitalWrite(ledW, LOW);
digitalWrite(ledN, LOW);
//selectLineTwo();
//Serial.println('angle');
}
else if(angle < -67.5 && angle > -112.5){
digitalWrite(ledW, HIGH);
digitalWrite(ledNE, LOW);
digitalWrite(ledE, LOW);
digitalWrite(ledSE, LOW);
digitalWrite(ledS, LOW);
digitalWrite(ledSW, LOW);
digitalWrite(ledN, LOW);
digitalWrite(ledNW, LOW);
//selectLineTwo();
// Serial.println('angle');
}
else if(angle < -112.5 && angle > -157.5){
digitalWrite(ledSW, HIGH);
digitalWrite(ledNE, LOW);
digitalWrite(ledE, LOW);
digitalWrite(ledSE, LOW);
digitalWrite(ledS, LOW);
digitalWrite(ledN, LOW);
digitalWrite(ledW, LOW);
digitalWrite(ledNW, LOW);
//selectLineTwo();
//Serial.println('angle');
}
buttonState = digitalRead(buttonPin);
COValue = analogRead(0);
MethaneValue = analogRead(1);
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
// if the current state is HIGH then the button
// wend from off to on:
buttonPushCounter++;
clearLCD();
}
lastButtonState = buttonState;
}
if(buttonPushCounter == 0){
selectLineOne();
delay(100);
Serial.print("Welcome...");
selectLineTwo();
delay(100);
Serial.print("Fool.");
delay(100);
}
else if(buttonPushCounter == 1){
selectLineOne();
delay(100);
Serial.print("Methane = ");
delay(100);
Serial.print(MethaneValue);
delay(100);
}
else if(buttonPushCounter == 2){
selectLineOne();
delay(100);
Serial.print("CO = ");
delay(100);
Serial.print(COValue);
delay(100);
}
if(buttonPushCounter >= 3){
buttonPushCounter = 0;
}
}
No comments:
Post a Comment