Еще один контакт!
У меня есть проект Arduino для управления скоростью двигателя на трех уровнях, обозначаемых тремя светодиодами, поэтому уровень 1 — это скорость 1, светодиод 1 и так далее для уровней 2/3.
Кроме того, я добавил индикатор низкого напряжения батареи, чтобы отслеживать уровень заряда батареи.
Я собираюсь использовать ATtiny45, который имеет 8 контактов (Vcc, GND, 1 аналоговый контакт, 5 цифровых контактов). Для проекта требуется 6 цифровых контактов и 1 аналоговый контакт, поэтому нужен только еще один контакт.
Я не хочу использовать расширитель или I2C, так как они усложнят проект, а он всего один пин!
Я могу использовать микроконтроллер большего размера, но это будет последний выбор.
Вот схема и код моего проекта:
//********************************************^************************************************
// https://forum.arduino.cc/t/control-motor-speed-with-npn-and-push-button-no-driver/1184925
//
//
//
// Version YY/MM/DD Comments
// ======= ======== ====================================================================
// 1.00 20/23/02 Running code
// 1.10 20/23/03 Added motor and LEDs OFF if switch pressed for >= 3 sec.
//
//
//
#define PRESSED HIGH
#define RELEASED LOW
#define ENABLED true
#define DISABLED false
#define LEDon HIGH
#define LEDoff LOW
#define MOTORoff 0
#define lipo A0
float lipoV = 0;
//GPIOs
const byte Button = 2;
const byte ledpin = 3;
const byte ledpin1 = 4;
const byte ledpin2 = 5;
const byte Motor = 9;
const byte heartbeatLED = 13;
const byte Red = 6;
//Variables
byte lastButton = RELEASED;
byte currSwitch;
int Speed_Level;
bool bCheckingSwitch = DISABLED;
//timing stuff
unsigned long heartbeatTime;
unsigned long switchesTime;
unsigned long threeSecondTime;
// s e t u p ( )
//********************************************^************************************************
void setup()
{
pinMode(Button, INPUT);
pinMode(lipo, INPUT);
pinMode(ledpin, OUTPUT);
pinMode(ledpin1, OUTPUT);
pinMode(ledpin2, OUTPUT);
pinMode(Motor, OUTPUT);
pinMode(heartbeatLED, OUTPUT);
pinMode(Red, OUTPUT);
} //END of setup()
// l o o p ( )
//********************************************^************************************************
void loop()
{
//************************************************ T I M E R heartbeatLED
//is it time to toggle the heartbeat LED ?
if (millis() - heartbeatTime >= 500ul)
{
//restart this TIMER
heartbeatTime = millis();
//toggle the heartbeat LED
if (digitalRead(heartbeatLED) == HIGH) digitalWrite(heartbeatLED, LOW);
else digitalWrite(heartbeatLED, HIGH);
}
//************************************************ T I M E R check switches
//is it time to check our switches ?
if (millis() - switchesTime >= 50ul)
{
//restart this TIMER
switchesTime = millis();
checkSwitches();
}
//************************************************ T I M E R three seconds
//if enabled, is it time to turn things OFF ?
if (bCheckingSwitch == ENABLED && millis() - threeSecondTime >= 2000ul)
{
//we are finished with this TIMER
bCheckingSwitch = DISABLED;
//restart the sequence
Speed_Level = -1;
analogWrite(Motor, MOTORoff);
digitalWrite(ledpin, LEDoff);
digitalWrite(ledpin1, LEDoff);
digitalWrite(ledpin2, LEDoff);
digitalWrite(Red, LEDoff);
}
} //END of loop()
// c h e c k S w i t c h e s ( )
//********************************************^************************************************
void checkSwitches()
{
byte state;
//************************************************ Button
state = digitalRead(Button);
//has there been a state change in the switch ?
if (lastButton != state)
{
//update to the new state
lastButton = state;
//*******************************
if (state == PRESSED)
{
//enable the TIMER
bCheckingSwitch = ENABLED;
//start the TIMER
threeSecondTime = millis();
}
//*******************
//the switch was released
else
{
//disable the TIMER
bCheckingSwitch = DISABLED;
Speed_Level++;
lipoV = analogRead(lipo);
//battery checker
if(lipoV < 680){
digitalWrite(Red,LEDon);
}
else
{
digitalWrite(Red,LEDoff);
}
//don't go over 3
if (Speed_Level >= 4)
{
Speed_Level = 0;
}
//*******************
if (Speed_Level == 1)
{
analogWrite(Motor, 50);
digitalWrite(ledpin, LEDon);
digitalWrite(ledpin1, LEDoff);
digitalWrite(ledpin2, LEDoff);
}
//*******************
else if (Speed_Level == 2)
{
analogWrite(Motor, 75);
digitalWrite(ledpin, LEDoff);
digitalWrite(ledpin1, LEDon);
digitalWrite(ledpin2, LEDoff);
}
//*******************
else if (Speed_Level == 3)
{
analogWrite(Motor, 100);
digitalWrite(ledpin, LEDoff);
digitalWrite(ledpin1, LEDoff);
digitalWrite(ledpin2, LEDon);
}
//*******************
else
{
analogWrite(Motor, MOTORoff);
digitalWrite(ledpin, LEDoff);
digitalWrite(ledpin1, LEDoff);
digitalWrite(ledpin2, LEDoff);
digitalWrite(Red,LEDoff);
}
}
}
}//END of checkSwitches()
//********************************************^************************************************
Могу ли я использовать tA0 в качестве ввода и вывода одновременно?
Или я могу уменьшить количество контактов светодиодов, то есть использовать 1 контакт для 2 светодиодов?
@Tito, 👍0
Обсуждение2 ответа
Лучший ответ:
В качестве (немного хакерского и бинарного :) ) предложения вы можете использовать всего два светодиода и освободить контакт следующим образом...
Уровень 1 — светодиод 1 включен, светодиод 2 выключен
Уровень 2 — светодиод 1 выключен, светодиод 2 включен
Уровень 3 – горит светодиод 1, горит светодиод 2
Это очень простое изменение ваших текущих настроек и кода
Альтернативно (как предложил @dandavis) используйте набор из 3 неопикселей и управляйте всего с 1 контакта
просто и легко, это то, что я хотел, @Tito
Вы можете попробовать чарлиплексирование своих светодиодов. Использование только 3 цифровых контактов можно подключить до 6 светодиодов. Веб-поиск по запросу «charlieplexing» Arduino» поможет вам начать работу.
- Что произойдет с ардуино, если не использовать резистор со светодиодом?
- Почему некоторые контакты Arduino Nano (D3, D4, A3, A4, A6, A7) не могут быть установлены на высокий уровень?
- Встроенные светодиоды HIGH и LOW кажутся перевернутыми
- Как подключить светодиодную RGB-матрицу 8x8 к Uno?
- Проводная связь Arduino с MCP23008 GPIO pin expander для включения светодиода нажатием кнопки
- Безопасно питать светодиодную ленту через ESP32 GPIO
- Как подключить светодиодную матрицу 1088AS к сервоконтроллеру PCA 9685? есть выход?
- Использование вывода светодиода для ввода
Вы можете объединить кнопку и светодиод, переключая ее между входами, считывая их, а затем возвращаясь к выходу. Пока вы делаете это более 50 раз в секунду, светодиод будет выглядеть нормально, а кнопка будет блокировать светодиод, обеспечивая визуальную обратную связь в качестве бонуса., @dandavis
@dandavis, можешь, пожалуйста, привести пример?, @Tito
Вообще, подумав об этом подробнее, я бы просто заменил ваши 3 светодиода состояния на неопиксели и завел все три+ с одного контакта. Для объединения вы подаете 1 кОм от 5 В к светодиоду, а затем заземляете. Кнопка расположена параллельно светодиоду. Включение и выключение светодиода - это просто
digitalWrite(x,1)
, чтобы прочитать кнопкуpinMode(x, INPUT);st=digitalRead(x);pinMode(x, OUTPUT);
чтобы переключиться обратно на просмотр светодиода., @dandavisЯ думаю, это будет очень сложно в кодировании, @Tito
Библиотека adafruit neopixel или fastLED довольно проста в использовании и позволяет легко менять цвета и яркость, что делает проект более эффектным. Другой вариант усложняет код, но это то, что вам нужно, когда простое оборудование заканчивается., @dandavis
@dandavis извините, я вас не уловил, я думаю, что мой код и настройка светодиодов соответствуют именно тому, что вы говорите: светодиоды подключаются от 1 кОм к 5 В, затем заземляются, как на моей схеме, и код, который вы сказали, находится в коде скетча!, @Tito
Чтобы измерить уровень заряда батареи, вам понадобится второй резистор между A0 и землей, иначе на выводе A0 все равно останется 9 В, что может привести к повреждению вашего Arduino., @PMF
@Тито изучи это https://wokwi.com/projects/361190433680191489, @jsotola