Hello guys,
I need to interface HX711 with ESP32 in deep sleep mode. That shouldn't be a problem because interfacing with HX711 is really simple, just putting some pins up, some pins down and read some pins and do some basic math.
The biggest challenge i'm facing right now is to work with 32 bits variable. At some point of the code i need to shift 1 bit left, and thats really hard to do because all 4 registers are 16 bits only. I'm having trouble right now at the line "jump b_lsb_1, 0x8000". Compiler gives me this error : "Jump adress is to far. Input text was eq.".
Code is below and i haven't finished yet, i'm trying to do part by part. If someone could please give me some advice of a easiest way to work with 32 bits variables on ULP or even a easiest way to interface HX711 with ULP ESP32, i would be very pleased.
PS: Sorry 4 PT-BR comments in the code , the parts that i have doubts are commented in english
Thank u very much,
Matheus
#include "soc/soc_ulp.h"
#include "soc/rtc_io_reg.h"
#include "soc/sens_reg.h"
#include "soc/rtc_cntl_reg.h"
.bss//Variaveis sao declaradas dentro da secao .bss
.global measurement_count
measurement_count: .long 0
.text//O codigo é feito dentro da secao .text
.global main
main://O codigo e iniciado aqui, equivale ao void setup()
jump loop
loop: //add0 = 9 adsk = 8
WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TS_S+9, 1, 1)//sobe add0
WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG, RTC_GPIO_OUT_DATA_W1TC_S+8, 1, 1)//desce adsk
le_add0:
READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S + 9, 1) // le gpio_num_15 = rtc gpio 13
and r0, r0, 1 // faz uma and do valor lido com 0x01
jumpr le_add0, 0, eq // se o valor de r0 for igual zero, volta para ler dnv r0
stage_rst
loop_count:
WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TC_S+8, 1, 1)//desce adsk
and r0, r1, 0x8000 // R0 = R1 & 0X8000
jumpr b_lsb_1, 0x8000, // if R1 (LSB BYte) MSB BIT is 1, R0 will be equal to 0x8000 then jump to b_lsb_1
jump b_lsb_0 // if R1(LSB Byte) MSB bit is 0, R0 will be 0x0000
b_lsb_0: // R1 MSB Bit equal 0
lsh r0, r1, 1 // shift 1 bit left from LSB Byte
mov r1, r0
lsh r0, r2, 1 // shift 1 bit left from R2( MSB Byte)
mov r2, r0
jump loop_count
b_lsb_1: // R1 MSB Bit equal 0
lsh r0, r1, 0x01 // shift 1 bit left from lsb byte
mov r1, r0
lsh r0, r2, 0x01 // shift 1 bit left from msb byte
add r2, r0, 1 // add 1 to the value that correspondsto MSB bit from LSB byte that now is LSB bit of MSB Byte.
jump loop_count
ULP - 32 bits arithmetics
Re: ULP - 32 bits arithmetics
Use two registers. Or if 16 bit resolution is enough, read 16 bits in and just clock the rest.
-
- Posts: 10
- Joined: Thu Feb 20, 2020 2:44 pm
Re: ULP - 32 bits arithmetics
Any idea on how can i read this 32 bits variable, that i got using ULP, in my main app? I have MSB byte in one register and LSB byte in another register. I need to get these two values in one 32 bits variable.
Re: ULP - 32 bits arithmetics
uint32_t val = (ulp_msb << 16) | (ulp_lsb & 0xFFFF);
-
- Posts: 10
- Joined: Thu Feb 20, 2020 2:44 pm
Re: ULP - 32 bits arithmetics
Hello guys, reliving this old topic. I sucessed on reading HX711 with ULP coprocessor. I achieve this a few days later my post here, but i completely forgot to post the code for those who may need to do this in future. Since ULP is a small processor, i tought easier to work just with the 24 bits decimal value read from HX711, instead of converting this decimal value to weight and then analysing the value. The system wake up if the value read from HX711 is higher than a threshold (that is calculated by main processor equivalent to an weight threshold). The comments are in portuguese, but i guess google translator can translate it easily
Code: Select all
#include "soc/soc_ulp.h"
#include "soc/rtc_io_reg.h"
#include "soc/sens_reg.h"
#include "soc/rtc_cntl_reg.h"
.data
.global trshHoldADMSB
trshHoldADMSB: .long 0x00
.global trshHoldADLSB
trshHoldADLSB: .long 0x00
.bss//Variaveis sao declaradas dentro da secao .bss
.global bytelsb
bytelsb: .long 0
.global bytemsb
bytemsb: .long 0
.global valorADMSB
valorADMSB: .long 0
.global valorADLSB
valorADLSB: .long 0
.global debugVar
debugVar: .long 0
.global contador
contador: .long 0
.global MediaZeroTaraMSB
MediaZeroTaraMSB: .long 0
.global MediaZeroTaraLSB
MediaZeroTaraLSB: .long 0
.text//O codigo é feito dentro da secao .text
.global main
main://O codigo e iniciado aqui, equivale ao void setup()
WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TS_S+12, 1, 1)//sobe add0
jump loop
loop: //add0 = 9 adsk = 8
move r3, 0x00
move r1, bytelsb
st r3, r1, 0
move r3, 0x00
move r2, bytemsb
st r3, r2, 0
WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TS_S+9, 1, 1)//sobe add0
WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG, RTC_GPIO_OUT_DATA_W1TC_S+8, 1, 1)//desce adsk
le_add0:
READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S + 9, 1) // le gpio_num_15 = rtc gpio 13
and r0, r0, 1 // faz uma and do valor lido com 0x01
jumpr le_add0, 1, eq // se o valor de r0 for igual 1, volta para ler dnv add0
stage_rst
loop_count:
WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TC_S+8, 1, 1)//sobe adsk
move r1, bytelsb
ld r1, r1, 0
move r2, bytemsb
ld r2, r2, 0
move r1, bytelsb
ld r1, r1, 0
move r2, bytemsb
ld r2, r2, 0
and r0, r1, 0x8000 // R0 = R1 & 0X8000
jumpr b_lsb_1, 32767, gt// if R1 (LSB BYte) MSB BIT is 1, R0 will be greater than 32767 then jump to b_lsb_1
b_lsb_0: // R1 MSB Bit equal 0
move r0, r1
lsh r0, r0, 1 // shift 1 bit left from LSB Byte
move r1, bytelsb
st r0, r1, 0
move r0, r2
lsh r0, r0, 1 // shift 1 bit left from MSB Byte
move r2, bytemsb
st r0, r2, 0
jump inc_count
b_lsb_1: // R1 MSB Bit equal 1
move r0, r1
lsh r0, r0, 0x01 // shift 1 bit left from lsb byte
move r1, bytelsb
st r0, r1, 0
move r0, r2
lsh r0, r0, 0x01 // shift 1 bit left from msb byte
add r0, r0, 1 // add 1 to the value corresponding to MSB bit from LSB byte that now is LSB bit of MSB Byte.
move r2, bytemsb
st r0, r2, 0
inc_count:
WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG, RTC_GPIO_OUT_DATA_W1TC_S+8, 1, 1)//desce adsk
READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S + 9, 1) // le gpio_num_15 = rtc gpio 13
and r0, r0, 1 // faz uma and do valor lido com 0x01
jumpr fim_loop, 0, eq // se o valor de r0 for igual zero significa q gpio esta baixo então n incrementa r1
move r1, bytelsb
ld r0, r1, 0
add r0, r0, 1
jump ovflw_soma, ov
move r3, bytelsb
st r0, r3, 0
jump fim_loop
ovflw_soma:
move r3, bytelsb
st r0, r3, 0
move r3, bytemsb
ld r0, r3, 0
add r0, r0, 1
st r0, r3, 0
fim_loop:
stage_inc 1
jumps loop_count, 24, lt
xor:
move r2, bytemsb
ld r2, r2, 0
WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TC_S+8, 1, 1)//sobe adsk
and r3,r2,0x0080
or r0,r2,0x0080
sub r0,r0,r3
sub r0,r0,r3
move r2, r0
move r3, valorADMSB
st r2, r3, 0
move r3, valorADLSB
move r1, bytelsb
ld r1, r1, 0
st r1, r3, 0
//lsb nao precisa de xor já que o valor feito o xor em 32bits é 0x00800000, portanto todo o LSB seria feito o xor com 0x00
// em que o resultado é igual a entrada.
fim:
WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG, RTC_GPIO_OUT_DATA_W1TC_S+8, 1, 1)//desce adsk
compair_trshHold:
move r2, trshHoldADMSB
ld r2, r2, 0
move r3, valorADMSB
ld r3, r3, 0
sub r0, r2, r3
jumpr msb_igual, 0, eq
jump wake_up, ov // overflow significa que r3 > r2 portanto vloadAD > threshHold
// msb ad menor q threshhold
move r3, debugVar
move r0, 0x05
st r0, r3, 0
jump loop
msb_igual:
move r3, debugVar
move r0, 0x07
st r0, r3, 0
move r2, trshHoldADLSB
ld r2, r2, 0
move r3, valorADLSB
ld r3, r3, 0
sub r0, r2, r3
move r1, contador
st r0, r1, 0
jump wake_up, ov // overflow significa que r3 > r2 portanto vloadAD > threshHold
jump loop
wake_up:
move r3, debugVar
move r0, 0x06
st r0, r3, 0
/* Check if the system can be woken up */
READ_RTC_FIELD(RTC_CNTL_LOW_POWER_ST_REG, RTC_CNTL_RDY_FOR_WAKEUP)
and r0, r0, 1
jump loop, eq
/* Wake up the SoC, end program */
wake
WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0)
halt
Re: ULP - 32 bits arithmetics
May be missing the difficulty but:
ntoh/hton
This seams an endian issue.
ntoh/hton
This seams an endian issue.
& I also believe that IDF CAN should be fixed.
Re: ULP - 32 bits arithmetics
Have anyone tested the code yet? I have tried it so far but, i got a constantly reset loop between wakeup caused by ULP and sleep.matheusmbg wrote: ↑Fri Nov 13, 2020 9:03 pmHello guys, reliving this old topic. I sucessed on reading HX711 with ULP coprocessor. I achieve this a few days later my post here, but i completely forgot to post the code for those who may need to do this in future. Since ULP is a small processor, i tought easier to work just with the 24 bits decimal value read from HX711, instead of converting this decimal value to weight and then analysing the value. The system wake up if the value read from HX711 is higher than a threshold (that is calculated by main processor equivalent to an weight threshold). The comments are in portuguese, but i guess google translator can translate it easily
Code: Select all
#include "soc/soc_ulp.h" #include "soc/rtc_io_reg.h" #include "soc/sens_reg.h" #include "soc/rtc_cntl_reg.h" .data .global trshHoldADMSB trshHoldADMSB: .long 0x00 .global trshHoldADLSB trshHoldADLSB: .long 0x00 .bss//Variaveis sao declaradas dentro da secao .bss .global bytelsb bytelsb: .long 0 .global bytemsb bytemsb: .long 0 .global valorADMSB valorADMSB: .long 0 .global valorADLSB valorADLSB: .long 0 .global debugVar debugVar: .long 0 .global contador contador: .long 0 .global MediaZeroTaraMSB MediaZeroTaraMSB: .long 0 .global MediaZeroTaraLSB MediaZeroTaraLSB: .long 0 .text//O codigo é feito dentro da secao .text .global main main://O codigo e iniciado aqui, equivale ao void setup() WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TS_S+12, 1, 1)//sobe add0 jump loop loop: //add0 = 9 adsk = 8 move r3, 0x00 move r1, bytelsb st r3, r1, 0 move r3, 0x00 move r2, bytemsb st r3, r2, 0 WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TS_S+9, 1, 1)//sobe add0 WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG, RTC_GPIO_OUT_DATA_W1TC_S+8, 1, 1)//desce adsk le_add0: READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S + 9, 1) // le gpio_num_15 = rtc gpio 13 and r0, r0, 1 // faz uma and do valor lido com 0x01 jumpr le_add0, 1, eq // se o valor de r0 for igual 1, volta para ler dnv add0 stage_rst loop_count: WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TC_S+8, 1, 1)//sobe adsk move r1, bytelsb ld r1, r1, 0 move r2, bytemsb ld r2, r2, 0 move r1, bytelsb ld r1, r1, 0 move r2, bytemsb ld r2, r2, 0 and r0, r1, 0x8000 // R0 = R1 & 0X8000 jumpr b_lsb_1, 32767, gt// if R1 (LSB BYte) MSB BIT is 1, R0 will be greater than 32767 then jump to b_lsb_1 b_lsb_0: // R1 MSB Bit equal 0 move r0, r1 lsh r0, r0, 1 // shift 1 bit left from LSB Byte move r1, bytelsb st r0, r1, 0 move r0, r2 lsh r0, r0, 1 // shift 1 bit left from MSB Byte move r2, bytemsb st r0, r2, 0 jump inc_count b_lsb_1: // R1 MSB Bit equal 1 move r0, r1 lsh r0, r0, 0x01 // shift 1 bit left from lsb byte move r1, bytelsb st r0, r1, 0 move r0, r2 lsh r0, r0, 0x01 // shift 1 bit left from msb byte add r0, r0, 1 // add 1 to the value corresponding to MSB bit from LSB byte that now is LSB bit of MSB Byte. move r2, bytemsb st r0, r2, 0 inc_count: WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG, RTC_GPIO_OUT_DATA_W1TC_S+8, 1, 1)//desce adsk READ_RTC_REG(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT_S + 9, 1) // le gpio_num_15 = rtc gpio 13 and r0, r0, 1 // faz uma and do valor lido com 0x01 jumpr fim_loop, 0, eq // se o valor de r0 for igual zero significa q gpio esta baixo então n incrementa r1 move r1, bytelsb ld r0, r1, 0 add r0, r0, 1 jump ovflw_soma, ov move r3, bytelsb st r0, r3, 0 jump fim_loop ovflw_soma: move r3, bytelsb st r0, r3, 0 move r3, bytemsb ld r0, r3, 0 add r0, r0, 1 st r0, r3, 0 fim_loop: stage_inc 1 jumps loop_count, 24, lt xor: move r2, bytemsb ld r2, r2, 0 WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TC_S+8, 1, 1)//sobe adsk and r3,r2,0x0080 or r0,r2,0x0080 sub r0,r0,r3 sub r0,r0,r3 move r2, r0 move r3, valorADMSB st r2, r3, 0 move r3, valorADLSB move r1, bytelsb ld r1, r1, 0 st r1, r3, 0 //lsb nao precisa de xor já que o valor feito o xor em 32bits é 0x00800000, portanto todo o LSB seria feito o xor com 0x00 // em que o resultado é igual a entrada. fim: WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG, RTC_GPIO_OUT_DATA_W1TC_S+8, 1, 1)//desce adsk compair_trshHold: move r2, trshHoldADMSB ld r2, r2, 0 move r3, valorADMSB ld r3, r3, 0 sub r0, r2, r3 jumpr msb_igual, 0, eq jump wake_up, ov // overflow significa que r3 > r2 portanto vloadAD > threshHold // msb ad menor q threshhold move r3, debugVar move r0, 0x05 st r0, r3, 0 jump loop msb_igual: move r3, debugVar move r0, 0x07 st r0, r3, 0 move r2, trshHoldADLSB ld r2, r2, 0 move r3, valorADLSB ld r3, r3, 0 sub r0, r2, r3 move r1, contador st r0, r1, 0 jump wake_up, ov // overflow significa que r3 > r2 portanto vloadAD > threshHold jump loop wake_up: move r3, debugVar move r0, 0x06 st r0, r3, 0 /* Check if the system can be woken up */ READ_RTC_FIELD(RTC_CNTL_LOW_POWER_ST_REG, RTC_CNTL_RDY_FOR_WAKEUP) and r0, r0, 1 jump loop, eq /* Wake up the SoC, end program */ wake WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0) halt
I set up trshHoldADLSB to 54464 and trshHoldADMSB to 128 then the reset loop disappeared. Unfortunately, when the thing (probably 500gr) is put on the scale. It won't wake up.
I thought do I miss understanding which variable I should set to put the threshold value in, but again, I don't have an experience yet with assembly language.
Who is online
Users browsing this forum: Bing [Bot], Majestic-12 [Bot] and 250 guests