Запись массива с типом данных float и вывод его в com-порт
- Войдите на сайт для отправки комментариев
Втр, 07/08/2018 - 20:11
Доброго времени суток, хотел сделать себе приблуду для страйкбольного привода чтобы мог стрелять очередями по 3 , 5 ... чтобы число выстрелов можно было прописать в програме...А также чтобы цыкл совершался полностью т. е. пружина должна быть аслаблена. НО что-то не выходит, в програмировании я новичок не судите строго за код. В основе всего сидит датчик тока ASC 712 он постоянно считывает показания тока, по этим показаниям по задумке программа отслеживает цикл (см скриншот ниже)и считает их колличество. я попытался вывести значения в ком порт при массиве float одни нули были, перевел данные float в int стали выводиться странные числа (см скриншот ниже).


/*
AEG контроллер
*/
const int sensorPin = A0;
int mVperAmp = 100; //коэф перевода для датчика тока 100 for 20A
int RawValue= 0;
int ACSoffset = 2500; // Значение напряжение м мВ при 0А.
float Voltage = 0; // Напряжение в мВ
float Amps = 0; //Сила тока
#define Pin_Button 3 //Пин к которому привязываем кнопку
#define Pin_MOSFET 4 //Пин к которому привязываем мосфет транзистор
#define Pin_Button_2 2 //Пин к которому привязываем кнопку которая упровляет колличеством выстрелов
#define quantity_shots 4 // Коичество выстрелов в очереди
boolean x = 0; //перепенная вкл/выкл режима стрелбы очередми
boolean flag = 0; // флажок для управления кнопкой стрельбы очерередями
boolean flag_2=0; //флажок для управление отсечкой огня
byte shots = 0; //Считает количество выстрелов
//----------------------------------------ФИЛЬТР ПО СТРЕДНЕМУ ЗНАЧЕНИЮ---------------------------------------
// функция считывает аналоговый вход заданное количество раз
// и возвращает отфильтрованное значение
int readMean(int pin, int samples){
// переменная для хранения суммы считанных значений
int sum = 0;
// чтение и складывание значений
for (int i = 0; i < samples; i++){
sum = sum + analogRead(pin);
}
// делим сумму значений на количество измерений
sum = sum/samples;
// возвращаем среднее значение
return sum;
}
//----------------------------------------МЕДИАННЫЙ ФИЛЬТР---------------------------------------------------
// функция считывает аналоговый вход заданное количество раз
// и возвращает медианное отфильтрованное значение
int readMedian (int pin, int samples){
// массив для хранения данных
int raw[samples];
// считываем вход и помещаем величину в ячейки массива
for (int i = 0; i < samples; i++){
raw[i] = analogRead(pin);
}
// сортируем массив по возрастанию значений в ячейках
int temp = 0; // временная переменная
for (int i = 0; i < samples; i++){
for (int j = 0; j < samples - 1; j++){
if (raw[j] > raw[j + 1]){
temp = raw[j];
raw[j] = raw[j + 1];
raw[j + 1] = temp;
}
}
}
// возвращаем значение средней ячейки массива
return raw[samples/2];
}
void setup(){
Serial.begin(115200);
pinMode(Pin_Button, INPUT_PULLUP);// Используем 3 пин для снятия значений с кнопки
pinMode(Pin_MOSFET, OUTPUT); // Пин (4) который открывает и закрывает мосфет транзистор
pinMode(Pin_Button_2, INPUT_PULLUP); // Используем 2 пин для снятия значений с кнопки
}
void loop(){
//---------------------------------РАСЕТ ЗНАЧЕНИЯ СИЛЫ ТОКА----------------------------------------------
RawValue = readMedian(sensorPin, 15);// Присваиваем переменной отфильтрованные значения по медианному фильтру
Voltage = (RawValue / 1024.0) * 5000; // Формула для подсчета напряжения в мВ
Amps = ((Voltage - ACSoffset) / mVperAmp);//Формула для подсчета силы тока в А
boolean butt=0;// переменная хранящая состояние кнопки
butt=!digitalRead(Pin_Button);//считывание с пина кнопки значений(инвертируем сигнал т.к. используем INPUT_PULLUP)
boolean butt_2 = 0; //Переменная хранящая состояние кнопки №2(кнопкп переключения режимов огня)
butt_2=!digitalRead(Pin_Button_2);
// Управление кнопкой стрельбы очередями
if (butt_2==1 && flag==0){
flag=1;
x=!x;
}
if(butt_2==0 && flag==1){
flag=0;
}
int lol=0;
lol=int(Amps);//переписывает float в int
//Serial.println(lol);
//---------------------------------АВТОМАТИЧЕСКАЯ СТРЕЛЬБА--------------------------------------------------
//Условие при котором двигатель включон
if(butt==1 && x==0){digitalWrite(Pin_MOSFET,HIGH);
}
//----------------------------------СТРЕЛЬБА ОЧЕРЕДЯМИ(не работает)-------------------------------------------------------
else if (butt==1 && x==1 && flag_2==0){digitalWrite(Pin_MOSFET, HIGH);
int raw_3[10];
for( int i=0; i<10; i++){
raw_3[i]=lol;
delay(30);
if (raw_3[i+1]<raw_3[i]){shots++; // условие которае считает количество выстрелов и дает отсечку
if (shots >= quantity_shots && butt==1){
digitalWrite(Pin_MOSFET, LOW); flag_2=1;
shots=0;// обнуляем счетчик
}
}
}
}
else if (butt==0 && x==1 && flag_2==1){
flag_2=0;
}
//-----------------------------------------------ТОРМОЗ---------------------------------------------------
else if (butt==0){// Если спуск отпущен отключает мосфет
int raw_2[10];
// Условие для поиска падения силы тока
for(int i=0; i<10; i++){
raw_2[i]=lol;
if(raw_2[i+1]<raw_2[i] && butt==0){
digitalWrite(Pin_MOSFET, LOW);
//Serial.println(raw_2[10]);
}
}
}
//Serial.println(shots);
//Serial.println(butt);
//Serial.println(x);
//Serial.print("\t Без фильтра = " ); //показать не фильтрованные значения
//Serial.print(RawValue);//показать не фильтрованные значения
//Serial.print("\t mV = "); // показать значение напряжения в мВ
//Serial.print(Voltage,3); //"3"- колличество знаков после запятой
//Serial.print("\t A = "); // показать значения силы тока
Serial.println("$");
Serial.println(Amps,3); // "3"- колличество знаков после запятой
Serial.println(";");
// Вывод фильтрованных значений
// выводим среднеизмеренное значение
//Serial.print("\t Cреднее= ");
//Serial.print(readMean(sensorPin, 15));
// выводим медианное отфильтрованное значение
//Serial.print("\t Медианное= ");
//Serial.print(readMedian(sensorPin, 15));
delay(10);
}
Код не соответсвует тому, что выводится - это печатал другой код.
Давайте-ка ещё раз код и ЕГО печать. Только печать не картинкой, а текстом (копипастом).
/* AEG контроллер */ const int sensorPin = A0; int mVperAmp = 100; //коэф перевода для датчика тока 100 for 20A int RawValue= 0; int ACSoffset = 2500; // Значение напряжение м мВ при 0А. float Voltage = 0; // Напряжение в мВ float Amps = 0; //Сила тока #define Pin_Button 3 //Пин к которому привязываем кнопку #define Pin_MOSFET 4 //Пин к которому привязываем мосфет транзистор #define Pin_Button_2 2 //Пин к которому привязываем кнопку которая упровляет колличеством выстрелов #define quantity_shots 4 // Коичество выстрелов в очереди boolean x = 0; //перепенная вкл/выкл режима стрелбы очередми boolean flag = 0; // флажок для управления кнопкой стрельбы очерередями boolean flag_2=0; //флажок для управление отсечкой огня byte shots = 0; //Считает количество выстрелов //----------------------------------------ФИЛЬТР ПО СТРЕДНЕМУ ЗНАЧЕНИЮ--------------------------------------- // функция считывает аналоговый вход заданное количество раз // и возвращает отфильтрованное значение int readMean(int pin, int samples){ // переменная для хранения суммы считанных значений int sum = 0; // чтение и складывание значений for (int i = 0; i < samples; i++){ sum = sum + analogRead(pin); } // делим сумму значений на количество измерений sum = sum/samples; // возвращаем среднее значение return sum; } //----------------------------------------МЕДИАННЫЙ ФИЛЬТР--------------------------------------------------- // функция считывает аналоговый вход заданное количество раз // и возвращает медианное отфильтрованное значение int readMedian (int pin, int samples){ // массив для хранения данных int raw[samples]; // считываем вход и помещаем величину в ячейки массива for (int i = 0; i < samples; i++){ raw[i] = analogRead(pin); } // сортируем массив по возрастанию значений в ячейках int temp = 0; // временная переменная for (int i = 0; i < samples; i++){ for (int j = 0; j < samples - 1; j++){ if (raw[j] > raw[j + 1]){ temp = raw[j]; raw[j] = raw[j + 1]; raw[j + 1] = temp; } } } // возвращаем значение средней ячейки массива return raw[samples/2]; } void setup(){ Serial.begin(115200); pinMode(Pin_Button, INPUT_PULLUP);// Используем 3 пин для снятия значений с кнопки pinMode(Pin_MOSFET, OUTPUT); // Пин (4) который открывает и закрывает мосфет транзистор pinMode(Pin_Button_2, INPUT_PULLUP); // Используем 2 пин для снятия значений с кнопки } void loop(){ //---------------------------------РАСЕТ ЗНАЧЕНИЯ СИЛЫ ТОКА---------------------------------------------- RawValue = readMedian(sensorPin, 15);// Присваиваем переменной отфильтрованные значения по медианному фильтру Voltage = (RawValue / 1024.0) * 5000; // Формула для подсчета напряжения в мВ Amps = ((Voltage - ACSoffset) / mVperAmp);//Формула для подсчета силы тока в А boolean butt=0;// переменная хранящая состояние кнопки butt=!digitalRead(Pin_Button);//считывание с пина кнопки значений(инвертируем сигнал т.к. используем INPUT_PULLUP) boolean butt_2 = 0; //Переменная хранящая состояние кнопки №2 butt_2=!digitalRead(Pin_Button_2); // Управление кнопкой стрельбы очередями if (butt_2==1 && flag==0){ flag=1; x=!x; } if(butt_2==0 && flag==1){ flag=0; } int lol=0; lol=int(Amps);//переписывает float в int //Serial.println(lol); //---------------------------------АВТОМАТИЧЕСКАЯ СТРЕЛЬБА-------------------------------------------------- //Условие при котором двигатель включон if(butt==1 && x==0){digitalWrite(Pin_MOSFET,HIGH); } //----------------------------------СТРЕЛЬБА ОЧЕРЕДЯМИ(не работает)------------------------------------------------------- else if (butt==1 && x==1 && flag_2==0){digitalWrite(Pin_MOSFET, HIGH); int raw_3[10]; for( int i=0; i<10; i++){ raw_3[i]=lol; delay(30); if (raw_3[i+1]<raw_3[i]){shots++; // условие которае считает количество выстрелов и дает отсечку if (shots >= quantity_shots && butt==1){ digitalWrite(Pin_MOSFET, LOW); flag_2=1; shots=0;// обнуляем счетчик } } } } else if (butt==0 && x==1 && flag_2==1){ flag_2=0; } //-----------------------------------------------ТОРМОЗ--------------------------------------------------- else if (butt==0){// Если спуск отпущен отключает мосфет int raw_2[10]; // Условие для поиска падения силы тока for(int i=0; i<10; i++){ raw_2[i]=lol; if(raw_2[i+1]<raw_2[i] && butt==0){ digitalWrite(Pin_MOSFET, LOW); Serial.println(raw_2[10]); Serial.println("---------------------"); } } } //Serial.println(shots); //Serial.println(butt); //Serial.println(x); //Serial.print("\t Без фильтра = " ); //показать не фильтрованные значения //Serial.print(RawValue);//показать не фильтрованные значения //Serial.print("\t mV = "); // показать значение напряжения в мВ //Serial.print(Voltage,3); //"3"- колличество знаков после запятой //Serial.print("\t A = "); // показать значения силы тока //Serial.println("$"); //Serial.println(Amps,3); // "3"- колличество знаков после запятой //Serial.println(";"); // Вывод фильтрованных значений // выводим среднеизмеренное значение //Serial.print("\t Cреднее= "); //Serial.print(readMean(sensorPin, 15)); // выводим медианное отфильтрованное значение //Serial.print("\t Медианное= "); //Serial.print(readMedian(sensorPin, 15)); delay(10); }Массив raw_2 описан в строке 115 как
intraw_2[10];Значит в нём 10 элементов с 0-го по 9-ый.
А в строке 121 Вы выводите на печать 10-ый элемент
Serial.println(raw_2[10]);которого в данном массиве попросту нет. И что Вы надеетесь увидеть?
Кстати, в строке 119 тоже есть выход за границы этого массива, т.к. i меняется от 0 до 9, а Вы исапользуете i+1
все ясно, я думал, что вывожу 10 элементов массива :(
Если нельзя использовать i+1, то как мне узнать когда будет спад на графике или можно не задавать границы массива ?
Извините за не скромность, но не могли бы вы глянуть раздел " стрельба очередми", я хочу сделать так, чтобы можно было задавать колличество выстрелов в 1 очереди.
за рание благодарю :)
Если нельзя использовать i+1, то как мне узнать когда будет спад на графике или можно не задавать границы массива ?
почему нельзя-то? - можно, только за пределы массива не выходите
Тогда как понять, что я выхожу за пределы массива, или проще не задавать границы int raw_2[]; , а в конце цикла вернуть колличество байт командой sizeof(), только я немного не понимаю как ее внедрить...
Тогда как понять, что я выхожу за пределы массива,
Ну, так и понять. Если он у Вас объявлен как [10], то следите, чтобы индекс был от 0 до 9.
или проще не задавать границы int raw_2[]; , а в конце цикла вернуть колличество байт командой sizeof(), только я немного не понимаю как ее внедрить...
Простите, это бред. А память то под массив кто выделит? Надо сначала указать сколько там элементов (выделить память) а потом уж с ними рабботать, а не наоборот. Почитайте про работау с массивами в Си. Иинформации навалом.
Хорошо :) с массивами я разберусь, но вот я не понимаю почему не работает мой режим стрельбы очередими. Там смысл такой: наполняеться массив данными с токового датчика и его элементы сравниваются и получаеться пока двигаетль взводит пружину ток растет, после происходит выстрел и двигатель работает в холостую (ток падает), пока секторная шестерня снова ( провернувший) не начнет взводить пружину и так по кругу. В это время программа считает количесво этих "спадов"(выстрелов) и сравнивает с тем количеством выстрелов которые указаны(пользователь сам указывает нужное ему кол-во). после достижения этого числа, прога должна остановиться и ждать пока снова не нажмут на спуск.
И вот когда я включаю режм стрельбы очередями, он не стреляет от слова вообще. Толи не успевает записаться массив толи что. подскажите пожалуйста, может я не вижу очевидного :с
Извините, я не понимаю, как я могу выйти за пределы массива, если он находится в цикле который подставляет индексы 0, 1, 2.... 9 и так покругу, массив просто перезаписываеться (ну покрайней мере, я так думаю)
Просто мне нужно чтобы массив "бежал" по данным идущим с датчика ( Бежит и сканирует данные)
данные с датчика -->========[==========]============-->
Извините, я не понимаю, как я могу выйти за пределы массива, если он находится в цикле который подставляет индексы 0, 1, 2.... 9 и так покругу,
Но Вы ведь используете i+1 в качестве индекса массива в строке №119! А чему, по Вашему, равно i+1, когда i равно 9? Вот Вы и вылезли, чего Вы тут не понимаете?
Извините пожалуйста, я достал своими вопросами, но я сталкнулся еще с 1 проблемой. Почему к переменной shots пребавляется 1 если условие не выполняеться. Вот что выводится:
//----------------------------------СТРЕЛЬБА ОЧЕРЕДЯМИ(не работает)------------------------------------------------------- else if (butt==1 && x==1 && flag_2==0){digitalWrite(Pin_MOSFET, HIGH); float raw_3[10]; for( int i=0; i<10; i++){ raw_3[i]=Amps; Serial.println(raw_3[i],6); // Сода можно списать задержку на 30 мс и будет по 4 выстрела if (raw_3[i]<raw_3[i-1]){shots++; // условие которае считает количество выстрелов и дает отсечку Serial.println(shots); if (shots >= quantity_shots){ digitalWrite(Pin_MOSFET, LOW); flag_2=1; shots=0;// обнуляем счетчик } } } } else if (butt==0 && x==1 && flag_2==1){ flag_2=0; }А кто Вам сказал, что оно не выполняется? Напечтайте побольше знаков и увидите, что выполняется. А лучше сравнивайте плавающие числа как положено, с погрешностью. И кстати, если уж печатаеть, так печатайте обе переменные одновременно, чтобы видеть нормально.