Hello,
I am currently working on a small stirrer with a BLDC motor for brewing beer. I mostly had the components in the basement, and it basically works quite well. Connected to the Arduino Uno is a DS18b20 sensor, which displays the temperature on the TM1637 display. However, I have two problems where you might be able to help me. Firstly, it doesn't work with a 9V power supply. It only works with the USB cable connected to the laptop. I'm using a 9V guitar pedal power supply with 120mA. Additionally, I want to analyze some data later in a Python program (temperature, speed, etc.). For this reason, I've also connected the SPEED output to the Arduino (and the GND). However, in the serial monitor, it doesn't show correct values for the speed. When the motor runs (at any speed), it sometimes alternates between displaying 0 RPM and 30 RPM. What could be the reason for this? Program codes and motor driver datasheet are attached.
#include <TM1637Display.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2 // Pin für den DS18B20-Sensor
#define CLK 3 // Pin CLK des TM1637-Displays
#define DIO 4 // Pin DIO des TM1637-Displays
#define SPEED_PIN 5 // Pin, an dem der SPEED-Ausgang des Treibers angeschlossen ist
#define MOTOR_POLE_PAIRS 2 // Anzahl der Motorpolpaare
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
TM1637Display display(CLK, DIO);
void setup() {
Serial.begin(9600);
sensors.begin();
display.setBrightness(0x0a); // Helligkeit einstellen (0-0x0f)
pinMode(SPEED_PIN, INPUT); // Den Pin für die Drehzahl als Eingang konfigurieren
}
void loop() {
// Temperatur aktualisieren
sensors.requestTemperatures();
float tempC = sensors.getTempCByIndex(0);
// Drehzahl auslesen
int pulseFrequency = digitalRead(SPEED_PIN);
int motorSpeed = (pulseFrequency * 60) / MOTOR_POLE_PAIRS; // Drehzahl berechnen unter Berücksichtigung der Polpaare
// Temperatur und Drehzahl im Terminal anzeigen
if (tempC != DEVICE_DISCONNECTED_C) {
Serial.print("Temperatur: ");
Serial.print(tempC);
Serial.println(" °C");
Serial.print("Drehzahl: ");
Serial.print(motorSpeed);
Serial.println(" U/min");
int temp = int(tempC);
display.showNumberDec(temp);
} else {
Serial.println("Fehler beim Lesen der Temperatur");
display.showNumberDec(8888);
}
delay(1000);
}
You mean the power supply is rated to handle a maximum current of 120mA? If so, I'm going to say that's likely an issue. The Arduino needs 50mA alone, how much does the seven segment display require? Grove states theirs is typical 27/max 80mA and the temp sensor active current I could find is 1mA. Seems close for my liking, if I'm understanding the 9V supply correctly.
I can't say I know that. I can make a somewhat educated guess based of things I have done and had to correct, that's all I can offer.
This tells me it works, or at least worked, as you want and you indicate a pretty good place to start looking.
I have often found that when things stopped working for me, it was that the devices were being power starved, happens all the time with just battery powered stuff when the batteries die.
You say it alternates between 0 and 30RPM. I don't know what condition creates the 30 RPM but a resetting Arduino sure could create a 0. If you have a 9V 1A DC power adapter, I'd use that and see. Seems like the easiest thing to try first anyway. Can't hurt to try.
#include <TM1637Display.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2 // Pin für den DS18B20-Sensor
#define CLK 3 // Pin CLK des TM1637-Displays
#define DIO 4 // Pin DIO des TM1637-Displays
#define SPEED_PIN 5 // Pin für den SPEED-Ausgang vom Treiber
#define ALARM_PIN 6 // Pin für den ALM-Ausgang vom Treiber
#define MOTOR_POLE_PAIRS 4 // Anzahl der Motorpolpaare
#define TIME_WINDOW 1000 // Zeitfenster in Millisekunden
volatile int pulseCount = 0; // Variable für die Anzahl der Pulsen
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
TM1637Display display(CLK, DIO);
void setup() {
Serial.begin(9600);
sensors.begin();
display.setBrightness(0x0a); // Helligkeit einstellen (0-0x0f)
pinMode(SPEED_PIN, INPUT_PULLUP);
pinMode(ALARM_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(SPEED_PIN), countPulses, RISING);
}
void loop() {
sensors.requestTemperatures(); // Temperatur aktualisieren
float tempC = sensors.getTempCByIndex(0); // Temperatur in Celsius lesen
if (tempC != DEVICE_DISCONNECTED_C) { // Überprüfen, ob ein gültiger Wert gelesen wurde
// Temperatur im Terminal anzeigen
Serial.print("Temperatur: ");
Serial.print(tempC);
Serial.println(" °C");
// Temperatur auf dem TM1637-Display anzeigen
int temp = int(tempC); // Temperatur auf ganze Zahl konvertieren
display.showNumberDec(temp); // Temperatur ohne Dezimalstelle auf dem Display anzeigen
} else {
// Fehlerbehandlung, wenn kein gültiger Wert gelesen werden kann
Serial.println("Fehler beim Lesen der Temperatur");
display.showNumberDec(8888); // Anzeige auf "8888" setzen, wenn ein Fehler auftritt
}
// Warten bis das Zeitfenster abgelaufen ist
delay(TIME_WINDOW);
// Anzahl der Impulse im Zeitfenster auslesen
int pulseCountSnapshot = pulseCount;
pulseCount = 0; // Reset pulse count for the next window
// Motordrehzahl basierend auf der Anzahl der Impulse und der Dauer des Zeitfensters berechnen
float motorSpeed = (pulseCountSnapshot * 60.0) / MOTOR_POLE_PAIRS / (TIME_WINDOW / 1000.0); // Drehzahl in U/min
// Anzeige der Motordrehzahl
Serial.print("Drehzahl: ");
Serial.print(motorSpeed);
Serial.println(" U/min");
}
void countPulses() {
pulseCount++; // Increment pulse count when a rising edge is detected
}
Thank you, I think I understand.
What do you think of this version?
#include <TM1637Display.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2 // Pin für den DS18B20-Sensor
#define CLK 3 // Pin CLK des TM1637-Displays
#define DIO 4 // Pin DIO des TM1637-Displays
#define SPEED_PIN 5 // Pin für den SPEED-Ausgang vom Treiber
#define ALARM_PIN 6 // Pin für den ALM-Ausgang vom Treiber
#define MOTOR_POLE_PAIRS 4 // Anzahl der Motorpolpaare
#define TIME_WINDOW 1000 // Zeitfenster in Millisekunden
volatile int pulseCount = 0; // Variable für die Anzahl der Pulsen
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
TM1637Display display(CLK, DIO);
void setup() {
Serial.begin(9600);
sensors.begin();
display.setBrightness(0x0a); // Helligkeit einstellen (0-0x0f)
pinMode(SPEED_PIN, INPUT_PULLUP);
pinMode(ALARM_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(SPEED_PIN), countPulses, RISING);
}
void loop() {
unsigned long startTime = millis(); // Zeitstempel vor dem Auslesen der Temperatur
sensors.requestTemperatures(); // Temperatur aktualisieren
float tempC = sensors.getTempCByIndex(0); // Temperatur in Celsius lesen
if (tempC != DEVICE_DISCONNECTED_C) { // Überprüfen, ob ein gültiger Wert gelesen wurde
// Temperatur im Terminal anzeigen
Serial.print("Temperatur: ");
Serial.print(tempC);
Serial.println(" °C");
// Temperatur auf dem TM1637-Display anzeigen
int temp = int(tempC); // Temperatur auf ganze Zahl konvertieren
display.showNumberDec(temp); // Temperatur ohne Dezimalstelle auf dem Display anzeigen
} else {
// Fehlerbehandlung, wenn kein gültiger Wert gelesen werden kann
Serial.println("Fehler beim Lesen der Temperatur");
display.showNumberDec(8888); // Anzeige auf "8888" setzen, wenn ein Fehler auftritt
}
unsigned long endTime = millis(); // Zeitstempel nach dem Auslesen der Temperatur
unsigned long elapsedTime = endTime - startTime; // Zeit für das Auslesen der Temperatur in Millisekunden
// Warten bis das Zeitfenster abgelaufen ist
long remainingTime = max(TIME_WINDOW - elapsedTime, 0); // Sicherstellen, dass die verbleibende Zeit nicht negativ wird
delay(remainingTime);
// Anzahl der Impulse im Zeitfenster auslesen
int pulseCountSnapshot = pulseCount;
pulseCount = 0; // Reset pulse count for the next window
// Motordrehzahl basierend auf der Anzahl der Impulse und der Dauer des Zeitfensters berechnen
float motorSpeed = (pulseCountSnapshot * 60.0) / MOTOR_POLE_PAIRS / (TIME_WINDOW / 1000.0); // Drehzahl in U/min
// Anzeige der Motordrehzahl
Serial.print("Drehzahl: ");
Serial.print(motorSpeed);
Serial.println(" U/min");
}
void countPulses() {
pulseCount++; // Increment pulse count when a rising edge is detected
}