Skip to content

Commit

Permalink
Added Plugin for HX711 Load Cell - Request letscontrolit#408 (letscon…
Browse files Browse the repository at this point in the history
…trolit#415)

* First draft

* Added Plugin for HX711 Load Cell

* Typo
  • Loading branch information
JK-de authored and psy0rz committed Jul 7, 2017
1 parent e0edd56 commit 8b6adac
Showing 1 changed file with 251 additions and 0 deletions.
251 changes: 251 additions & 0 deletions src/_P067_HX711_Load_Cell.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
//#######################################################################################################
//#################################### Plugin 063: _P067_HX711_Load_Cell ################################
//#######################################################################################################

// ESPEasy Plugin to scan a 24 bit AD value from a load cell chip HX711
// written by Jochen Krapf ([email protected])

// Electronics:
// Connect SCL to 1st GPIO and DOUT to 2nd GPIO. Use 3.3 volt for VCC.

// Datasheet: https://cdn.sparkfun.com/datasheets/Sensors/ForceFlex/hx711_english.pdf


#ifdef PLUGIN_BUILD_TESTING

#define PLUGIN_067
#define PLUGIN_ID_067 67
#define PLUGIN_NAME_067 "HX711 Load Cell [TESTING]"
#define PLUGIN_VALUENAME1_067 "Weight"

// #include <*.h> no lib required


#ifndef CONFIG
#define CONFIG(n) (Settings.TaskDevicePluginConfig[event->TaskIndex][n])
#endif
#ifndef PIN
#define PIN(n) (Settings.TaskDevicePin[n][event->TaskIndex])
#endif

int32_t Plugin_067_OversamplingValue = 0;
int16_t Plugin_067_OversamplingCount = 0;


void initHX711(int16_t pinSCL, int16_t pinDOUT)
{
digitalWrite(pinSCL, LOW);
pinMode(pinSCL, OUTPUT);

pinMode(pinDOUT, INPUT_PULLUP);
}


boolean isReadyHX711(int16_t pinSCL, int16_t pinDOUT)
{
return (!digitalRead(pinDOUT));
}

int32_t readHX711(int16_t pinSCL, int16_t pinDOUT, uint8_t mode)
{
int32_t value = 0;
int32_t mask = 0x00800000;

for (byte i = 0; i < 24; i++)
{
digitalWrite(pinSCL, HIGH);
delayMicroseconds(1);
digitalWrite(pinSCL, LOW);
if (digitalRead(pinDOUT))
value |= mask;
delayMicroseconds(1);
mask >>= 1;
}

for (byte i = 0; i < (mode+1); i++)
{
digitalWrite(pinSCL, HIGH);
delayMicroseconds(1);
digitalWrite(pinSCL, LOW);
delayMicroseconds(1);
}

if (value & 0x00800000) //negative?
value |= 0xFF000000; //expand sign bit to 32 bit

return value;
}


boolean Plugin_067(byte function, struct EventStruct *event, String& string)
{
boolean success = false;

switch (function)
{
case PLUGIN_DEVICE_ADD:
{
Device[++deviceCount].Number = PLUGIN_ID_067;
Device[deviceCount].Type = DEVICE_TYPE_DUAL;
Device[deviceCount].Ports = 0;
Device[deviceCount].VType = SENSOR_TYPE_SINGLE;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].ValueCount = 1;
Device[deviceCount].SendDataOption = true;
Device[deviceCount].TimerOption = true;
Device[deviceCount].TimerOptional = false;
Device[deviceCount].GlobalSyncOption = true;
break;
}

case PLUGIN_GET_DEVICENAME:
{
string = F(PLUGIN_NAME_067);
break;
}

case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_067));
break;
}

case PLUGIN_WEBFORM_LOAD:
{
addFormCheckBox(string, F("Oversampling"), F("oversampling"), CONFIG(0));

String optionsMode[3] = { F("Channel A, Gain 128"), F("Channel B, Gain 32"), F("Channel A, Gain 64") };
addFormSelector(string, F("Mode"), F("mode"), 3, optionsMode, NULL, CONFIG(1));

addFormTextBox(string, F("Offset"), F("Plugin_067_offset"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3], 3), 15);

addFormSubHeader(string, F("Two Point Calibration"));

addFormCheckBox(string, F("Calibration Enabled"), F("Plugin_067_cal"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);

addFormNumericBox(string, F("Point 1"), F("Plugin_067_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0]);
string += F(" &#8793; ");
addTextBox(string, F("Plugin_067_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);

addFormNumericBox(string, F("Point 2"), F("Plugin_067_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1]);
string += F(" &#8793; ");
addTextBox(string, F("Plugin_067_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);

success = true;
break;
}

case PLUGIN_WEBFORM_SAVE:
{
CONFIG(0) = isFormItemChecked(F("oversampling"));

CONFIG(1) = getFormItemInt(F("mode"));

Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3] = getFormItemFloat(F("Plugin_067_offset"));

Settings.TaskDevicePluginConfig[event->TaskIndex][3] = isFormItemChecked(F("Plugin_067_cal"));

Settings.TaskDevicePluginConfigLong[event->TaskIndex][0] = getFormItemInt(F("Plugin_067_adc1"));
Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0] = getFormItemFloat(F("Plugin_067_out1"));

Settings.TaskDevicePluginConfigLong[event->TaskIndex][1] = getFormItemInt(F("Plugin_067_adc2"));
Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1] = getFormItemFloat(F("Plugin_067_out2"));

success = true;
break;
}

case PLUGIN_INIT:
{
int16_t pinSCL = PIN(0);
int16_t pinDOUT = PIN(1);

String log = F("HX711: GPIO: SCL=");
log += pinSCL;
log += F(" DOUT=");
log += pinDOUT;
addLog(LOG_LEVEL_INFO, log);

if (pinSCL >= 0 && pinDOUT >= 0)
{
initHX711(pinSCL, pinDOUT);
}

success = true;
break;
}

case PLUGIN_FIFTY_PER_SECOND:
{
int16_t pinSCL = PIN(0);
int16_t pinDOUT = PIN(1);

if (Plugin_067_OversamplingCount < 250)
if (pinSCL >= 0 && pinDOUT >= 0)
if (isReadyHX711(pinSCL, pinDOUT))
{
int32_t value = readHX711(pinSCL, pinDOUT, CONFIG(1));

if (CONFIG(0)) //Oversampling?
{
Plugin_067_OversamplingValue += value;
Plugin_067_OversamplingCount ++;
}
else //use last value
{
Plugin_067_OversamplingValue = value;
Plugin_067_OversamplingCount = 1;
}
}

success = true;
break;
}

case PLUGIN_READ:
{
String log = F("HX711: Value: ");

if (Plugin_067_OversamplingCount > 0)
{
UserVar[event->BaseVarIndex] = (float)Plugin_067_OversamplingValue / Plugin_067_OversamplingCount;
Plugin_067_OversamplingValue = 0;
Plugin_067_OversamplingCount = 0;

UserVar[event->BaseVarIndex] += Settings.TaskDevicePluginConfigFloat[event->TaskIndex][3]; //Offset

log += String(UserVar[event->BaseVarIndex], 3);

if (Settings.TaskDevicePluginConfig[event->TaskIndex][3]) //Calibration?
{
int adc1 = Settings.TaskDevicePluginConfigLong[event->TaskIndex][0];
int adc2 = Settings.TaskDevicePluginConfigLong[event->TaskIndex][1];
float out1 = Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0];
float out2 = Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1];
if (adc1 != adc2)
{
float normalized = (float)(UserVar[event->BaseVarIndex] - adc1) / (float)(adc2 - adc1);
UserVar[event->BaseVarIndex] = normalized * (out2 - out1) + out1;

log += F(" = ");
log += String(UserVar[event->BaseVarIndex], 3);
}
}
}
else
{
log += F("NO NEW VALUE");
}

addLog(LOG_LEVEL_INFO,log);
success = true;
break;
}

}
return success;
}

#endif

0 comments on commit 8b6adac

Please sign in to comment.