HX711, WeightSensor, LoadCell (old Title: Reading a 7-Segment Display with the Imp?!)

@beardedinventor: Can you help me with the hardware hookup on your blog post. I can not find any documentation on the Aria board you used in the blog. I am using an Imp002 EVB, and I do not know which pins of the EVB to connect the HX711 for the SPI-like data transfer to work. I assume I have to replace spi257 with spi189 since Pin 2 is also connected to the Red led on the board. I am not sure about the clk and the data pins though. Any help in this matter would be appreciated.

Thanks

@MobileWave, you can still use spi257, but you may see the LED flash during pin 2’s use. Looking at the code, I’d say you can connect the EVB using the same pins as the Aria-based example, ie. 1, 2 and 7.

Thanks a lot. I have the code running as is.

Hi Guys,
I have a follow up to the code provided in the blog post. I can see in the read_weight function that the imp is pulsing the clk pin 24 times and converting the 24 bit data received from HX711 to a decimal number. This works fine when the output from HX711 is positive. How should I modify it to handle 2’s complemented negative output from HX711. Typical Arduino libraries XOR the leading bit of the 24 bit output with 1 and handle the data in an unsigned integer. Any help would be appreciated.

`function read_weight(){
    //This is bit banged so we 
    //bind calls to local variables
    //to speed things up.
    //Takes about 2.2mS to do the read
    local sw  = spi.write.bindenv(spi);
    local dr  = data.read.bindenv(data);
    local val = 0;

    for(local i = 24; i >= 0; i--){
        sw(PULSE);
        val += dr() ? math.pow(2, i) : 0;
    }

    return (val-ZERO_OFFSET)/GAIN;  //Value in grams
}`

You should be seeing 25 pulses. I actually think there might be a bug in my original code as rereading the datasheet you need to do 25 pulses but only the first 24 produce valid data. I think it should be something like:
`
for(local i = 23; i >= 0; i–){
sw(PULSE);
val += dr() ? math.pow(2, i) : 0;
}
sw(PULSE); // Extra pulse to reset DOUT

val = (val << 8) >> 8; //Make this into a signed 24 bit value

return (val-ZERO_OFFSET)/GAIN;  //Value in grams

I also included a line which sign extends val to make it a 32-bit signed number. Since the sign bit is at bit 24 rather than 32, we shift it up by 8 to put it into the sign position then we shift it back down by 8 and Squirrel automatically sign extends for us so the upper 8 bits will match the sign bit. This yields a properly signed number. Here was my test case:
local val = 0x00FFFFFF; //In 24-bit, 2-compliment this should be -1
server.log(val); // Logs 16777215
val = (val << 8) >> 8;
server.log(val); // Logs -1
`

Note, with these changes you will need to recompute ZERO_OFFSET and GAIN (they should be half of what they were before).

Thanks. I am trying to run this code and will tweak to adjust the gain and offset. In the meanwhile can you confirm that I have to typecast the variable val as int to get but shifting to work. I tried to run your code as is and was getting an error that was fixed by modifying to the following code

function read_weight(){
//This is bit banged so we
//bind calls to local variables
//to speed things up.
//Takes about 2.2mS to do the read
local sw = spi.write.bindenv(spi);
local dr = data.read.bindenv(data);
local val = 0;

 for(local i = 23; i >= 0; i--){
    sw(PULSE);
    val+= dr() ? math.pow(2, i) : 0;
}
sw(PULSE); // Extra pulse to reset DOUT

local val = (val.tointeger() << 8) >> 8; //Make this into a signed 24 bit value

return (val-ZERO_OFFSET)/GAIN;  //Value in grams

}

I can’t see why you would need to cast val as an integer, but if it’s working then it shouldn’t hurt.

The result of math.pow() is a float. It would be (perhaps microscopically) more efficient to use (1<<i) instead of math.pow(2,i).

Peter

Guys. Thanks for the response. I had bought two electric scales from Ebay and had pulled a load cell out of one of the electric scales for this experiment. After fixing the code as suggested by @brandon, and empirically finding out the values of offset and gain, I am measuring the same weight with the electric scale and the load cell + hx711 + electric imp.

Hey , I was trying to port the library from dfrobot.com/image/data/SEN0160/Arduino%20sample%20code.zip
This is the code I have converted so far , I am using pin257(spi) and pin 1(data)
` const uint8_t _pin_dout;
const uint8_t _pin_slk;
long _offset;
float _scale;
Hx711(uint8_t pin_din, uint8_t pin_slk);

Hx711::Hx711(uint8_t pin_dout, uint8_t pin_slk) :
	_pin_dout(pin_dout), _pin_slk(pin_slk)
{
	hardware.pin257.configure(DIGITAL_OUT);
	hardware.pin1.configure(ANALOG_IN);

	//digitalWrite(_pin_slk, HIGH);
            hardware.spi257.write(1);
	delayMicroseconds(100);
	//digitalWrite(_pin_slk, LOW);
            hardware.spi257.write(0);

	averageValue();
	this->setOffset(averageValue());
	this->setScale();
}


function getValue()
{
	byte data[3];

	while (hardware.pin1.read());

	for (byte j = 0; j < 3; j++)
	{
		for (byte i = 0; i < 8; i++)
		{
			//digitalWrite(_pin_slk, HIGH);
			hardware.spi257.write(1);
			bitWrite(data[2 - j], 7 - i, hardware.pin1.read();
			//digitalWrite(_pin_slk, LOW);
			hardware.spi257.write(0);
		}
	}

	//digitalWrite(_pin_slk, HIGH);
	hardware.spi257.write(1);
	//digitalWrite(_pin_slk, LOW);
	hardware.spi257.write(0);

	return ((long) data[2] << 16) | ((long) data[1] << 8) | (long) data[0];
}
function averageValue(byte times = 25)
{
	long sum = 0;
	for (byte i = 0; i < times; i++)
	{
		sum += getValue();
	}

return sum / times;
}
funstion setOffset(long offset)
{
	_offset=offset;
}
function setScale(float scale = 1100.f)
{
	_scale = scale;
}
function getGram()
{
	long val = (averageValue() - _offset);
	return (float) val / _scale;
}
function bitWrite(value, bit, bitvalue) 
{
	return (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
}


` 

I am merging the .cpp and the .h files . Do help me out.
Thanxy

Generally, drop your type declarations and check the syntax of your class declarations/instances. For a lot more guidance on porting to imp from Arduino, see ‘Porting Arduino Code to the imp’.

The post at https://community.electricimp.com/blog/imp-load-cells/ seems to be dead/down. Searching through the blog to which I’m redirected in that time frame doesn’t seem to yield results. Is this info archived anywhere?

Thanks!

Wayback machine FTW: https://web.archive.org/web/20160606084340/https://community.electricimp.com/blog/imp-load-cells/

(the code is still here: https://gist.github.com/bbharris/53f4351af704867b4df0 )

Thanks, Hugo. For some reason, perhaps my not using a trailing slash, it wasn’t finding it for me. I saw the gist still there, but I figured perhaps there as a repo outside the bbharris user. Reading the run-down (at least for a coding neophyte like myself), it makes more sense what the pictly stuff was doing in there. I can flip it out for a simple https put to a web server for my needs.