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