1 /*
2  * Author: Rafael da Mata Neri <rafael.neri@gmail.com>
3  * Copyright (c) 2015 Intel Corporation.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 #include <iostream>
23 #include <fstream>
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdexcept>
28 #include "hx711.h"
29 
30 using namespace upm;
31 using namespace std;
32 
HX711(uint8_t data,uint8_t sck,uint8_t gain)33 HX711::HX711(uint8_t data, uint8_t sck, uint8_t gain) {
34     mraa_result_t error = MRAA_SUCCESS;
35 
36     this->m_dataPinCtx = mraa_gpio_init(data);
37     if (this->m_dataPinCtx == NULL) {
38         throw std::invalid_argument(std::string(__FUNCTION__) +
39                                     ": Couldn't initialize DATA pin.");
40     }
41 
42     this->m_sckPinCtx = mraa_gpio_init(sck);
43     if (this->m_sckPinCtx == NULL) {
44         throw std::invalid_argument(std::string(__FUNCTION__) +
45                                     ": Couldn't initialize CLOCK pin.");
46     }
47 
48     error = mraa_gpio_dir (this->m_dataPinCtx, MRAA_GPIO_IN);
49     if (error != MRAA_SUCCESS) {
50         throw std::invalid_argument(std::string(__FUNCTION__) +
51                                     ": Couldn't set direction for DATA pin.");
52     }
53 
54     error = mraa_gpio_dir (this->m_sckPinCtx, MRAA_GPIO_OUT);
55     if (error != MRAA_SUCCESS) {
56         throw std::invalid_argument(std::string(__FUNCTION__) +
57                                     ": Couldn't set direction for CLOCK pin.");
58     }
59 
60     this->setGain(gain);
61 }
62 
~HX711()63 HX711::~HX711() {
64     mraa_result_t error = MRAA_SUCCESS;
65 
66     error = mraa_gpio_close (this->m_dataPinCtx);
67     if (error != MRAA_SUCCESS) {
68         mraa_result_print(error);
69     }
70 
71     error = mraa_gpio_close (this->m_sckPinCtx);
72     if (error != MRAA_SUCCESS) {
73         mraa_result_print(error);
74     }
75 }
76 
read()77 unsigned long HX711::read() {
78     unsigned long Count = 0;
79 
80     while (mraa_gpio_read(this->m_dataPinCtx));
81 
82     for (int i=0; i<GAIN; i++)
83     {
84         mraa_gpio_write(this->m_sckPinCtx, 1);
85         Count = Count << 1;
86         mraa_gpio_write(this->m_sckPinCtx, 0);
87         if(mraa_gpio_read(this->m_dataPinCtx))
88         {
89             Count++;
90         }
91     }
92 
93     mraa_gpio_write(this->m_sckPinCtx, 1);
94     Count = Count ^ 0x800000;
95     mraa_gpio_write(this->m_sckPinCtx, 0);
96 
97     return (Count);
98 }
99 
setGain(uint8_t gain)100 void HX711::setGain(uint8_t gain){
101     switch (gain) {
102         case 128:       // channel A, gain factor 128
103             GAIN = 24;
104             break;
105         case 64:        // channel A, gain factor 64
106             GAIN = 26;
107             break;
108         case 32:        // channel B, gain factor 32
109             GAIN = 25;
110             break;
111     }
112 
113     mraa_gpio_write(this->m_sckPinCtx, 0);
114     read();
115 }
116 
readAverage(uint8_t times)117 unsigned long HX711::readAverage(uint8_t times){
118     unsigned long sum = 0;
119     for (uint8_t i = 0; i < times; i++) {
120         sum += read();
121     }
122     return sum / times;
123 }
124 
getValue(uint8_t times)125 double HX711::getValue(uint8_t times){
126     return readAverage(times) - OFFSET;
127 }
128 
getUnits(uint8_t times)129 float HX711::getUnits(uint8_t times){
130     return getValue(times) / SCALE;
131 }
132 
tare(uint8_t times)133 void HX711::tare(uint8_t times){
134     double sum = readAverage(times);
135     setOffset(sum);
136 }
137 
setScale(float scale)138 void HX711::setScale(float scale){
139     SCALE = scale;
140 }
141 
setOffset(long offset)142 void HX711::setOffset(long offset){
143     OFFSET = offset;
144 }
145