Как обработать сигнал с драйвера HX711 используя прерывания

Я только начинаю свой путь освоения ардуино. Возник вопрос, который я пока не могу осилить самостоятельно. Есть тензодатчик с драйвером HX711 и ардуино. Задача получить показания используя прерывания. Т. е. как только значение на датчике изменилось, прервать выполнение основной программы и получить значение и вернуться к выполнению основного цикла.

#include <HX711.h>

#define SENSOR_DT_PIN 2
#define SENSOR_SCK_PIN 3

HX711 sensor;
volatile int weight;
float sensorCalibration = 0.014822222; // Значение подбирается в ручную 

void setup() {
  Serial.begin(9600);

  sensor.begin(SENSOR_DT_PIN, SENSOR_SCK_PIN);
  sensor.set_scale();
  sensor.tare();
  sensor.set_scale(sensorCalibration);

  attachInterrupt(0, getWeight, CHANGE);
}
void loop(){
// Какой-то код 
}

void getWeight() {
  weight =  sensor.get_units()*0.035274;
}

Данный код не работает. Может кто знает или подскажет где искать решение?

я уже начинаю боятся сегодня… :grinning:

а что у НХ711 есть выход инициации прерывания ?

2 лайка

Надо написать нормальный автомат, который будет включать прерывание когда надо их ждать, и выключать при первом срабатывании, иначе одному богу известно, что за фарш получится тут. И в исходниках библиотеки покопаться, чтобы понять, что там вообще происходит и как оно склеится с таким режимом.

Так не пойдёт?

attachInterrupt(0, getWeight, LOW);
...
void getWeight() {
  weight =  sensor.read();
}

Приводя код, где практически вся работа в некоторой библиотеке происходит, неплохо бы ссылку на эту библиотеку показывать.
Возможно, это вот она GitHub - bogde/HX711: An Arduino library to interface the Avia Semiconductor HX711 24-Bit Analog-to-Digital Converter (ADC) for Weight Scales. ?
Так вот, там в её описании есть ссылки на другие подобные библиотеки. В одной из них вроде как даже пытаются сделать как раз то, что Вы хотите - с прерыванием. Поглядите, может она Вам лучше подойдёт. По крайней мере, может из самого примера что-то полезное вытянете.

мне кажется пока ты клок не дернешь, он данные не начнет отдавать…

Учту на будущее.

Спасибо посмотрю и изучу.

Имеете ввиду выход сигнала с самого драйвера?

ну да
не я посмотрел что его нет и понял что вы хотите по первому фронту на дата пине инициировать чтение, но что бы дата заколыхалась, надо дергать клоком сначала.
ну это так, навскидку и даташит по диагонали.

Да вроде он сам лапу опускает по готовности и ждёт клоканья.

Извиняюсь за тупой вопрос, а что такое клокать? :sweat_smile:

Сигнал CLK

А поллингом не проще? Вроде сама шина-то не быстрая, зачем там прерывания?

ТС, может саму задачу изложите, а не тот способ что Вы выбрали?

вот из даташита

Reference Driver(C)
//-------------------------------------------------------------------
sbit ADDO = P1^5;
sbit ADSK = P0^0;
unsigned long ReadCount(void){
   unsigned long Count;
   unsigned char i;
   ADDO=1;
   ADSK=0;
   Count=0;
   while(ADDO);
   for (i=0;i<24;i++){
     ADSK=1;
     Count=Count<<1;
     ADSK=0;
     if(ADDO) Count++;
   }
   ADSK=1;
   Count=Count^0x800000;
   ADSK=0;
   return(Count);
} 

я так понял, клок в даун, ждем пока дата опустится, и пошли читать, клок ап 1мксек клок даун, читаем дату, ну и так в зависимости от разрешения.

или как то по другому?

Я не пойму, зачем это все, если инициирует обмен данными все одно мастер.
Разве чип НХ711 умеет отслеживать изменения сам?

да вот и я о том же…

Есть моменты когда основной код программы может зайти в бесконечный цикл. Цикл ждёт пока пользователь не нажмёт на кнопку или пока не изменится вес. У меня есть реализация где я тупо вызываю в нескольких местах метод getWeight. Просто подумал что можно дело как-то автоматизировать.

int weight;
void loop(){
   weight = getWeight();
   if(weight > 0){
      //Идут расчёты
      flag = true;
      while(flag){
      //Здесь я жду пока пользователь нажмёт на кнопку или пока не изменится вес
      // В этом случае я буду вызывать повторно метод getWeight()
      // Вот я подумал если это сделать с помошью прерывания так как меньше вызовов метода будет тем самым и быстрее работать. А таких циклов пока что у меня несколько
      }
   }
}

int getWeight() {
  return sensor.get_units()*0.035274;
}

Т.е. хочу избавиться от лишних проверок и реагировать только на изменения

Да я экзампл к библиотеке глянул, там сразу read()в лупе дергается. А read() сводится к ожиданию LOW и вычитке с клоканьем.

1). Это не драйвер, а АЦП.
2). Те экземпляры, которые попадались мне сильно шумят, один и тот же груз дает всегда разные результаты даже с усреднением.
3). Дешевые тензодатчики под нагрузкой плывут, чтобы получить более-менее достоверные результаты нужно снять нагрузку, установить 0, и только после этого взвешивать.

так и надо делать

1 лайк