Идеи для поделок
Есть старые наушники. Купи дешёвый Bluetooth модуль и сделай беспроводные наушники, а стерео усилитель сможешь подключить к мобильнику и проигрывать на нём любимые мелодии прямо из интернета или с минифлешки
Дешёвый небольшой блок питания с электронным управлением для отладки схем и заряда аккумуляторов
Измеритель расстояния на Arduino
Текст кода дальномера (до 400см):
#include <NewPing.h>
#define TRIGGER_PIN 13
#define ECHO_PIN 4
#define MAX_DISTANCE 400
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
float dist_3[3] = {0.0, 0.0, 0.0}; // массив для хранения трёх последних измерений
float middle, dist, dist_filtered;
float k;
byte i, delta;
unsigned long dispIsrTimer, sensTimer;
int anodPins[] = {A1, A2, A3, A4}; // Задаем пины для кажого разряда
int segmentsPins[] = {5, 6, 7, 8, 9, 10, 11, 12}; //Задаем пины для каждого сегмента (из 7 + 1(точка))
void setup() {
for (int i = 0; i < 4; i++) pinMode(anodPins[i], OUTPUT);
for (int i = 0; i < 8; i++) pinMode(segmentsPins[i], OUTPUT);
//Определяем вводы и выводы
pinMode(TRIGGER_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
}
//{A, B, C, D, E, F, G,DP}
int seg[12][8] = {
{1, 1, 1, 1, 1, 1, 0, 0}, //Цифра 0
{0, 1, 1, 0, 0, 0, 0, 0}, //Цифра 1
{1, 1, 0, 1, 1, 0, 1, 0}, //Цифра 2
{1, 1, 1, 1, 0, 0, 1, 0}, //Цифра 3
{0, 1, 1, 0, 0, 1, 1, 0}, //Цифра 4
{1, 0, 1, 1, 0, 1, 1, 0}, //Цифра 5
{1, 0, 1, 1, 1, 1, 1, 0}, //Цифра 6
{1, 1, 1, 0, 0, 0, 0, 0}, //Цифра 7
{1, 1, 1, 1, 1, 1, 1, 0}, //Цифра 8
{1, 1, 1, 1, 0, 1, 1, 0}, //Цифра 9
{0, 0, 0, 0, 0, 0, 1, 0}, //Знак -
{0, 0, 0, 0, 0, 0, 0, 0} //Пустой разряд
};
int err[4][8] = {
{0, 0, 0, 0, 0, 0, 0, 0}, //Пусто
{1, 0, 0, 1, 1, 1, 1, 0}, //E
{0, 0, 0, 0, 1, 0, 1, 0}, //r
{0, 0, 0, 0, 1, 0, 1, 0} //r
};
static int arr[4][8]; // Переменная-массив для хранения данных, которые не нужно каждый раз пересчитывать
float value = 0.0;
void loop() {
if (millis() - sensTimer > 60) { // измерение и вывод каждые 60 мс
// счётчик от 0 до 2
// каждую итерацию таймера i последовательно принимает значения 0, 1, 2, и так по кругу
if (i > 1) i = 0;
else i++;
dist_3[i] = (float)sonar.ping() / 57.5; // получить расстояние в текущую ячейку массива
dist = middle_of_3(dist_3[0], dist_3[1], dist_3[2]); // фильтровать медианным фильтром из 3ёх последних измерений
delta = abs(dist_filtered - dist); // расчёт изменения с предыдущим
if (delta > 1) k = 0.7; // если большое - резкий коэффициент
else k = 0.1; // если маленькое - плавный коэффициент
dist_filtered = dist * k + dist_filtered * (1 - k); // фильтр "бегущее среднее"
// вывести
value = dist_filtered;
getDigits(value);
sensTimer = millis();
// сбросить таймер
}
displayMessage(arr);
}
// медианный фильтр из 3ёх значений
float middle_of_3(float a, float b, float c) {
if ((a <= b) && (a <= c)) {
middle = (b <= c) ? b : c;
}
else {
if ((b <= a) && (b <= c)) {
middle = (a <= c) ? a : c;
}
else {
middle = (a <= b) ? a : b;
}
}
return middle;
}
void getDigits (float value) {
Serial.println("");
// Выдаем ошибку на те значения, которые не можем показать
if ((value >= 10000) ||
(value <= -1000)) {
for (int i = 0; i < 4; i++) { // Каждый разряд по очереди
for (int k = 0; k < 8; k++) {// Каждый сегмент по очереди - исходя из заданной карты
arr[i][k] = err[i][k];
}
}
return; // Выходим
}
int digits = 4; // У нас 4 разряда
if (value < 0) digits = 3; // Из-за минуса один символ убирается*/
// Делим число на 2 группы - отдельно целую часть и дробную.
int intPart = (int)abs(value);
int intLength = ((String)intPart).length(); // Смотрим, сколько разрядов занимает целая часть
char valueChars[8]; // По нормальному float в String преобразовать нельзя, поэтому...
dtostrf(value, 5, 4, valueChars); //... копируем данные float в массив chars[]
// На дробную часть у нас остается разрядов: digits-intLength
String valueStr = valueChars; // Теперь с текстовым форматом можно работать
// Serial.print("valueStr: "); Serial.println(valueStr);
int fracIndex = valueStr.indexOf("."); // Получаем индекс начала дробной части
String fracPartStr = valueStr.substring(fracIndex + 1, valueStr.length()); // Выделяем цифры дробной части
int fracDigits = digits - intLength;
fracPartStr = fracPartStr.substring(0, fracDigits); // Вычленяем цифры, которые будут выводиться на дисплей
// Serial.print("fracDigits: "); Serial.println(fracDigits);
// Serial.print("fracPartStr: "); Serial.println(fracPartStr);
int fracInt = fracPartStr.toInt(); // Переменная для проверки, нужно ли что-то выводить, если нули, то нет
// Serial.print("fracInt: "); Serial.println(fracInt);
// Собираем строку для отображения
String output = (value < 0) ? "-" : "";
output += (String)intPart;
String outputFrac = ((digits - intLength <= 0) || (fracInt == 0)) ? "" : ((String)"." + fracPartStr);
output += (String)outputFrac;
// Дополняем символы спереди, если цифр слишком мало, например для "-1" делаем " -1"
String spaces = " ";
digits = 4;
if (~output.indexOf(".")) digits += 1;
if (output.length() < digits) output = spaces.substring(0, digits - output.length()) + output;
// Формирум данные для показа:
int dig = -1;
for (int i = 0; i < output.length(); i++) {
String _char = output.substring(i, i + 1);
if (_char != ".") dig += 1; // Точка не занимает сегмент - увеличиваем на 1
int actualdigit = 11; // По умолчанию пустой символ
if ((_char == "-")) {
actualdigit = 10;
}
else if (_char == " " || _char == ".") {
}
else {
actualdigit = _char.toInt();
}
if (_char == ".") {
arr[dig][7] = 1; // Если нужно - ставим точку
}
else {
for (int n = 0; n <= 7; n++) {
arr[dig][n] = seg[actualdigit][n];
}
}
}
}
void displayMessage(int dig[4][8]) {
for (int i = 0; i < 4; i++) { // Каждый разряд по очереди
for (int k = 0; k < 8; k++) {// Каждый сегмент по очереди - исходя из заданной карты
digitalWrite(segmentsPins[k], ((dig[i][k] == 1) ? LOW : HIGH));
}
digitalWrite(anodPins[i], HIGH);
delay(1);
digitalWrite(anodPins[i], LOW);
}
}
Телеграфный ключ для обучения азбуки Морзе из подручных материалов. Работает от аккумулятора. Можно слушать не только через встроенный микродинамик, но и подключить наушники, а заряжать через USB