Джойстик на цифровых пинах
- Войдите на сайт для отправки комментариев
Сб, 23/04/2022 - 14:35

Создал отдельную тему из-за непонятного феномена по мотивам емкостного сенсора из соседней темы. Сделал скетч для джойстика:
#define sens_X 4
#define sens_Y 12
#define seria 10
int TIK_X=0;
int TIK_Y=0;
void setup() {
Serial.begin(9600);
}
void loop() {
sensor_data();
delay(200);
}
void sensor_data() {
///////////////////////////////////////////////////////////////////////////////////////////////
TIK_X=0;
for(int i=0;i<seria;i++)// делаем серию замеров
{
int tik_X = 0;
pinMode (sens_X, OUTPUT);//
delay(1);
pinMode (sens_X, INPUT); // установливаем ВХОД замеряем время зарядки кнопки
while (!digitalRead(sens_X)) { //пока не будет лог1, считаем tik-и
tik_X++;
}
TIK_X=TIK_X+tik_X;
}
TIK_X=TIK_X/seria;// вычисляем среднее значение в серии
Serial.print(TIK_X); //пишем усреднённый результат
Serial.print(" ");
///////////////////////////////////////////////////////////////////////////////////////////////
TIK_Y=0;
for(int i=0;i<seria;i++)// делаем серию замеров
{
int tik_Y = 0;
pinMode (sens_Y, OUTPUT);//
delay(1);
pinMode (sens_Y, INPUT); // установливаем ВХОД замеряем время зарядки кнопки
while (!digitalRead(sens_Y)) { //пока не будет лог1, считаем tik-и
tik_Y++;
}
TIK_Y=TIK_Y+tik_Y;
}
TIK_Y=TIK_Y/seria;// вычисляем среднее значение в серии
Serial.println(TIK_Y); //пишем усреднённый результат
///////////////////////////////////////////////////////////////////////////////////////////////
}
всё работает, в нейтральном положении в мониторе идут числа около 90. При манипуляциях рычагом значения по осям меняются "+-" от 20 до 160. Решил разделить функцию на две по осям:
#define sens_X 4
#define sens_Y 12
#define seria 10
void setup() {
Serial.begin(9600);
}
void loop() {
sensor_X_data();
sensor_Y_data();
delay(200);
}
void sensor_X_data() {
///////////////////////////////////////////////////////////////////////////////////////////////
int TIK_X=0;
for(int i=0;i<seria;i++)// делаем серию замеров
{
int tik_X = 0;
pinMode (sens_X, OUTPUT);//
delay(1);
pinMode (sens_X, INPUT); // установливаем ВХОД замеряем время зарядки кнопки
while (!digitalRead(sens_X)) { //пока не будет лог1, считаем tik-и
tik_X++;
}
TIK_X=TIK_X+tik_X;
}
TIK_X=TIK_X/seria;// вычисляем среднее значение в серии
Serial.print(" ");
Serial.println(TIK_X); //пишем усреднённый результат
///////////////////////////////////////////////////////////////////////////////////////////////
}
void sensor_Y_data() {
///////////////////////////////////////////////////////////////////////////////////////////////
int TIK_Y=0;
for(int i=0;i<seria;i++)// делаем серию замеров
{
int tik_Y = 0;
pinMode (sens_Y, OUTPUT);//
delay(1);
pinMode (sens_Y, INPUT); // установливаем ВХОД замеряем время зарядки кнопки
while (!digitalRead(sens_Y)) { //пока не будет лог1, считаем tik-и
tik_Y++;
}
TIK_Y=TIK_Y+tik_Y;
}
TIK_Y=TIK_Y/seria;// вычисляем среднее значение в серии
Serial.print(" ");
Serial.println(TIK_Y); //пишем усреднённый результат
///////////////////////////////////////////////////////////////////////////////////////////////
}
ничего не поменялось. Потом решил в программе читать только один переменный резистор, закомментировав строку sensor_Y_data();...
... и неожиданно нейтраль стала выдавать 127 вместо 90, а амплитуда от 25 до 138, аналогично и на второй оси при исключении чтения второй.
Как такое может быть? Как может влиять на время зарядки одного конденсатора присутствие в программе опроса второго?
как показывает моя длительная практика уровень логической единицы в реале вещь весьма непостоянная и колеблется от 1.5-1.6 вольта на 5 вольтовой логике, компаратор решит проблему
колеблется от 1.5-1.6 вольта на 5 вольтовой логике
Соответствующие колебания получаемых значений также минимальны и не влияют на описываемую странность.
delay(1); точно хватает для разрядки конденсатора ?
delay(1); точно хватает для разрядки конденсатора ?
Да, хватает, пробовал 2 и больше. Кажется я понял как надо поменять исходную идею этого метода, сейчас по экспериментирую.
Для корректной работы надо использовать замеры времени зарядки конденсатора до пороговых значений напряжения, а не значения прироста счётчика:
////////////////////////////////////////////////////////////////////////// /* #define sens 4 void setup() { Serial.begin(9600); } void loop() { sensor_data(); delay(1000); } void sensor_data() { int tik = 0; pinMode (sens, OUTPUT);// digitalWrite (sens, LOW); // устанавливаем ВЫХОД и 0 для замера времени разрядки кнопки delayMicroseconds(10); pinMode (sens, INPUT); // установливаем ВХОД замеряем время зарядки кнопки while (!digitalRead(sens)) { //пока не будет лог1, считаем tik-и tik++; } Serial.println(tik); //пишем результат } */ //////////////////////////////////////////////////////////////////////// #define sens 4 void setup() { Serial.begin(9600); } void loop() { sensor_data(); delay(1000); } void sensor_data() { int tik = 0; pinMode (sens, OUTPUT);//устанавливаем ВЫХОД и 0 для замера времени разрядки кнопки delay(1); pinMode (sens, INPUT); // установливаем ВХОД замеряем время зарядки кнопки long tik_ = micros(); while (!digitalRead(sens)) { //пока не будет лог1, считаем tik-и tik = micros()-tik_; } Serial.println(tik); //пишем результат } ////////////////////////////////////////////////////////////////////////моросит чуть более 2%, греть чип не пробовал
Всё таки проблема программная, мне не понятна её природа - почему значение tik зависит от варианта скетча в таком виде:
17while (!digitalRead(sens)) { //пока не будет лог1, считаем tik-и18tik++;19}и работает правильно-независимо при таком:
38while(!digitalRead(sens)) {//пока не будет лог1, считаем tik-и39tik = micros()-tik_;40}Вот для джойстика ещё правильный вариант:
#define sens_X 4 #define sens_Y 12 #define seria 10 void setup() { Serial.begin(9600); } void loop() { sensor_data(); delay(200); } void sensor_data() { /////////////////////////////////////////////////////////////////////////////////////////////// int TIK_X=0; int TIK_Y=0; for(int i=0;i<seria;i++)// делаем серию замеров { int tik_X = 0; int tik_Y = 0; pinMode (sens_X, OUTPUT);// pinMode (sens_Y, OUTPUT);// delay(1); pinMode (sens_X, INPUT); // установливаем ВХОД замеряем время зарядки кнопки pinMode (sens_Y, INPUT); // установливаем ВХОД замеряем время зарядки кнопки long tik_Yy =0; long tik_Xx = tik_Yy = micros(); while (!digitalRead(sens_X)&&!digitalRead(sens_Y)) { //пока не будет лог1, считаем tik-и tik_X=micros()-tik_Xx; tik_Y=micros()-tik_Yy; } while (!digitalRead(sens_X)) { //пока не будет лог1, считаем tik-и tik_X=micros()-tik_Xx; } while (!digitalRead(sens_Y)) { //пока не будет лог1, считаем tik-и tik_Y=micros()-tik_Yy; } TIK_X=TIK_X+tik_X; TIK_Y=TIK_Y+tik_Y; } TIK_X=TIK_X/seria;// вычисляем среднее значение в серии TIK_Y=TIK_Y/seria;// вычисляем среднее значение в серии Serial.print(TIK_X); //пишем усреднённый результат Serial.print(" "); Serial.println(TIK_Y); //пишем усреднённый результат /////////////////////////////////////////////////////////////////////////////////////////////// }