Перейти к содержанию

Работа С Массивом. Одно И Двум - Мерный Массив. Проблемка.


ukr823f

Рекомендуемые сообщения

Здравствуйте товарищи. Требуется ваша помощь. Эксперементирую по работе с массивами и вот возникла такая проблема. Немогу понять как извлечь из двумерного массива, нужное мне значение. Устройство представим элементарное. Дроссельная заслонка на машине, и лампочка допустим на выходе. Чем сильнее нажимаем на дроссельную заслонку, тем ярче загорается лампочка. Это для примера привёл, а так на самом деле другим устройством управлять но принцип тот же. Я сделал два двумерных массива.

первый - процент нажатия дроссельной заслонки в зависимости от напряжения на АЦП

TPS,V / %TPS

0 1 2 3 4 5 6 7 8 9 10 (индекс в массиве, это для наглядности)

0 10 20 30 40 50 60 70 80 90 100 (процент открытия дросселя)

0 0,45 0,9 1,35 1,80 2,25 2,70 3,15 3,60 4,05 4,50 (напряжения на ДПДЗ)

второй - скважность ШИМ в зависимости от нажатия дроссельной заслонки

TPS,% / DUTY

0 1 2 3 4 5 6 7 8 9 10 (индекс в массиве)

0 10 20 30 40 50 60 70 80 90 100 - процент открытия дроссельной заслонки

0 30 70 100 127 150 190 255 255 255 255 - скважность 8бит ШИМ

Вот так выглядят объявления массивов и переменных.



int TPS_V;//напряжение в вольтах
int TPS_perc; // процент открытия дроссельной заслонки
char duty; //переменная скважности ШИМ
char TPS_percent[2][11]{};
char TPS_duty[2][11]{};

и вот теперь сама проблема. Как мне допустим при половине нажатия на педаль и напряжение на ДПДЗ достать значение 50%

ВОт формула которую думал применить - но она неправильная. Здесь первая - это чтение значения АЦП и перевод его в вольты, а вторая это как раз попытка вытащить нужное мне значение открытия дроссельной заслонки. В первом индексе [0] - мы указываем что нам нужно вытаскивать цифру из нулевой строки массива, а вот как столбец нужный определить. Ведь столбец то мы по индексу от 0 до 10 только можем указать...

TPS_V=(read_adc(0)*5)/1024; //Читаем канал ADC0 и переводим его значение в вольты
TPS_perc=TPS_percent[0][TPS_V];

// попытка получить процент открытия дросселя

Вобщем вот такая проблема...

Изменено пользователем ukr823f
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Чёто Вы всё в кучу смешали, и доступ к массиву, и АЦП, и проценты, и какие-то заслонки, лампочки педали, дроссели, .... Совершенно не понятно, в чём у Вас проблема.

По вопросу (как извлечь из двумерного массива) :

c=arr[a][b];

a,b - индексы, по которым извлекается значение. В c это значение укладывается.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Чёто Вы всё в кучу смешали, и доступ к массиву, и АЦП, и проценты, и какие-то заслонки, лампочки педали, дроссели, .... Совершенно не понятно, в чём у Вас проблема.

Мне нужно извлечь из массива значение скважности ШИМ, в зависимости от напряжения на входе АЦП

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Если ацп 8-битный, то всего 256 возможных значений. Потому создаете массив с 256 элементами, и ложите в него требуемую скважность (например при половине напряжения результат АЦП - 127, скважность должна быть к примеру 30, это значит что элемент с порядковым номером 127 должен содержать с себе число, задающее скважность 30). извлекаете элементарно:

скважность=массив[результат преобразования ацп]

Любой, заслуживающий внимания, опыт приобретается себе в убыток...

Ссылка на комментарий
Поделиться на другие сайты

Мне нужно извлечь из массива значение скважности ШИМ, в зависимости от напряжения на входе АЦП
А мне иногда нужно чтобы кто-то извлёк из моего кошелька деньги, в зависимости от стоимости пива, и сходил в магазин. Для этого я узнаю цену, извлекаю из кошелька нужную сумму и даю её ходящему за пивом.

В чём КОНКРЕТНО проблема ? Не умеете извлекать из массива ? Или мерить значение АЦП ?

Ссылка на комментарий
Поделиться на другие сайты

Вот так выглядят объявления массивов и переменных.

Вобщем вот такая проблема...

осталось выяснить зачем здесь вообще нужен двухмерный массив... когда нужен массив структур???

и проблема отпадет сама собой...

Ссылка на комментарий
Поделиться на другие сайты

с АЦП работать умею.

Смотрите. Я вычислил результат преобразования АЦП по этой формуле. Тут у нас просто прочиталось напряжение от 0 до 5 вольт.

TPS_V=(read_adc(0)*5)/1024; //Читаем канал ADC0 и переводим его значение в вольты

И вот по вот этому массиву в зависимости от напряжения мне нужно менять скважность ШИМ. График ШИМ нелинеен, то есть при 2,5В будет 50% скважность (127), а при 2,7 вольтах уже 100% ШИМ (255)

Вот массив с данными скважности

0 10 20 30 40 50 60 70 80 90 100 - процент открытия дроссельной заслонки

0 30 70 100 127 150 190 255 255 255 255 - скважность 8бит ШИМ

второй массив как раз вычисляет процент открытия заслонки в зависимости от напряжения на входе АЦП

0 10 20 30 40 50 60 70 80 90 100 (процент открытия дросселя)

0 0,45 0,9 1,35 1,80 2,25 2,70 3,15 3,60 4,05 4,50 (напряжения на ДПДЗ)

И вот что невыходит. Допустим напряжение АЦП - 1.8Вольт .Как теперь из этих двух массивов нам выдать скважность ШИМ которая должна быть 127 судя по данным из двух массивов

Изменено пользователем ukr823f
Ссылка на комментарий
Поделиться на другие сайты

0 10 20 30 40 50 60 70 80 90 100 - процент открытия дроссельной заслонки

0 30 70 100 127 150 190 255 255 255 255 - скважность 8бит ШИМ

Вот Ваша формула зависимости :

y = 3E-05x4 - 0,0032x3 + 0,0984x2 + 2,5175x - 0,4545

Вбивайте её и не нужно будет никаких массивов.

График :

Лист Microsoft Excel.rar

Ссылка на комментарий
Поделиться на другие сайты

Товарищи, всё было бы так просто, если бы данные не приходилось менять. То есть нам допустим нужны другие значения напряжений или скважности ШИМ. С помощью UART можно будет всё поменять .

Массив - это у меня как таблица.

Это как аналогия как хранится допустим таблица углов зажигания в зависимости от оборотов и нагрузки.

Изменено пользователем ukr823f
Ссылка на комментарий
Поделиться на другие сайты

Допустим напряжение АЦП - 1.8Вольт
Зачем переводить в вольты и делать лишние телодвижения ? есть зависимсоть скважности от АЦП, от этих данных и отталкивайтесь.
Ссылка на комментарий
Поделиться на другие сайты

Смотрите. Я вычислил результат преобразования АЦП по этой формуле
С разрешением 1 В если в целых числах. А в дробных такую задачу можно решать только для вывода на экран, и то в числах с фиксированной точкой намного лучше.
График ШИМ нелинеен
График ШИМ достаточно линеен для большинства применений, включая даже усиление звука.
то есть при 2,5В будет 50% скважность (127), а при 2,7 вольтах уже 100% ШИМ (255)
Скважность ШИМ не зависит от напряжения.

.

Определитесь, что на входе контроллера и что хотите получить на выходе, игнорируя технические подробности остальной схемы. Контроллер ничего не знает о заслонках и педалях, для него есть только логические значения и уровни напряжения (только для модуля АЦП). Потом сформулируйте в тех же терминах, как контроллер должен переводить входные данные в выходные.

P.S. Название темы абсолютно не соответствует содержанию.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Товарищи, всё было бы так просто, если бы данные не приходилось менять. То есть нам допустим нужны другие значения напряжений или скважности ШИМ. С помощью UART можно будет всё поменять .

Тогда этот ответ самый актуальный для Вас :

Если ацп 8-битный, то всего 256 возможных значений. Потому создаете массив с 256 элементами, и ложите в него требуемую скважность (например при половине напряжения результат АЦП - 127, скважность должна быть к примеру 30, это значит что элемент с порядковым номером 127 должен содержать с себе число, задающее скважность 30). извлекаете элементарно:

скважность=массив[результат преобразования ацп]

Ссылка на комментарий
Поделиться на другие сайты

Ну попробую объяснить проще.

У нас есть контроллер, переменный резистор который изменяет напряжение от 0 до 5В и есть светодиод который управляется ШИМои (8 БИТ).

Теперь - Я допустим хочу чтобы светодиод пдавно увеличивал яркость с увеличением напряжения. То есть было

0В - светодиод не горит (ШИМ=0)

стало 2,5В - светодиод горит в пол силы (ШИМ = 127)

а потом стало 5В и светодиод загорелся на полную мощность (ШИМ=255)

Но допустим друг тоже себе такое захотел, но ему ненравиться такая последовательность работы

Он хочет чтобы было при

0В - светодиод горит на 10% (ШИМ =13)

1В - светодиод горит в пол силы (ШИМ=127)

3В - светодиод горит опять в 10% (ШИМ=13)

4В - свтеодид горит в 80% (ШИМ равен 200)

5В - светодиод опять горит в пол силы (ШИМ равен 127)

И вот кажды такойтоварищ хочет настраивать под себя этот сетодиодик. Соответсвенно нам нужна таблица настройки яркости светодиода в зависимости от напряжения на входе АЦП. Ведь массив это есть та самая таблица, которую мы можем изменять.

Так я думаю более понятно объяснил?

Тогда этот ответ самый актуальный для Вас :

Это я понял - и это элементарно и просто. Но допустим у меня АЦП с разрешением 10бит, выходит нужно табличку делать в 1024 значения?

И ещё вопрос. Вот допустим у меня будет два потенциомера и в зависимости от напряжений на них выбираем нужную нам скважность из двумерного массива. Это выходит даже при 8бит шиме - таблица будет иметь размер 256х256? Как она тогда поместиться нам в контроллер.... ПРошу прощения за глупые возможно вопросы, но вот столкнулся и надо всё таки разобраться с этой проблемой.

Изменено пользователем ukr823f
Ссылка на комментарий
Поделиться на другие сайты

Вряд ли там нужна такая точность. Можно взять 7,6 бит и массив, соответственно 128, 64 элемента.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Так я думаю более понятно объяснил?

Да поняли уже все, что Вам нужно. Сразу надо было с этого начинать, а не про заслонки с педалями писать.

В таком случае у Вас остаётся только 1 вариант - с созданием массива, размером с кол-во шагов, и заполнением его значениями скважности.

ЗЫ: На предыдущий пост обратите внимание, совет хороший. Во внимание нужно будет брать старшие биты значений АЦП.

Ссылка на комментарий
Поделиться на другие сайты

ок, хорошая идея про уменьшение разрешения АЦП.

Пожалуйста, расскажите - как тогда создают такие таблицы

Они выходит просто допустим обороты делят на 1000 и получают индекс для индекса столбцов массива?

и делят процент открытия дроссельной заслонки на 10 и получают индекс для строк массива?

example_zps7904553e.jpg

Ссылка на комментарий
Поделиться на другие сайты

В таком случае у Вас остаётся только 1 вариант - с созданием массива, размером с кол-во шагов, и заполнением его значениями скважности.

Хотя, варинат с формулой тоже можно применить, подкидывать только в контроллер коэффициенты. Но, для такой точности, компилятор должен поддерживать полноценный (64 бит) double. Иначе просто точности не хватит.
как тогда создают такие таблицы
Если известна зависимость, то по формуле вычислить каждое значение не составит труда.
Ссылка на комментарий
Поделиться на другие сайты

Они выходит просто допустим обороты делят на 1000 и получают индекс для индекса столбцов массива?

Необязательно делить, это сильно нагружает МК. Достаточно считать с точностью до 500 об/мин.

Любой массив - линейная последовательность данных в памяти. В Вашем случае двумера столбец умножается на строку и получается адрес ячейки, содержащей требуемое значение.

Ссылка на комментарий
Поделиться на другие сайты

То есть чтобы уменьшить таблиуц до размерности 16, при 8 битном ШИМе, мне нужно просто значение 8бит ШИМ делить на16

Допустим у нас 2,5В=127(это код АЦП при 8 БИТ ШИМе), А чтобы переделать его в 4Бит ШИМ мы делаем:

127 / 16 = 8.

Правильно?

Ссылка на комментарий
Поделиться на другие сайты

Да, правильно.

А из значения АЦП выкидываете 4 младших бита (это будет тоже деление на 16).

Я просто плохо разбираюсь как число 127 перевести в бинарную систему и откинуть 4 младших бита. На калькуляторе легко это выходит, а вот в Си коде для меня это пока труднодоступная задача Знаю что там сдвиг используется.... вобщем мне в десятках проще счиатть. Хотя ясное дело что для контроллера это дополнительная вычислительная нагрузка.

Ссылка на комментарий
Поделиться на другие сайты

Сдвинуть вправо на 4.

var>>=4; // Деление на 16

Или тупо :

var/=16;

Что эквивалентно друг другу в конечном результате. Естественно, только для беззнаковых переменных.

Ссылка на комментарий
Поделиться на другие сайты

Спасибо большое за советы. же запустил первый проект с одномерным массивом. Ну тогда нужно пробовать учиться работать с двумерным массивом но чтоб правильно.

На предыдущей странице указывали что по табличке на картинке = необязательно значение оборотов делить на 1000 чтобы получить индекс столбца. Писали что это не совсем правильно и затратно по нагрузке для контроллера. А как тогда проще допустим

при значении оборотов 3200 (RPM) и нажатию на педаль газа на 50 % (TPS) извлечь данные из таблички?

example_zps7904553e.jpg

И вот прикрепляю рабочий проект на аттини13 для работы с массивом. авось кому-то пригодиться

#include <tiny13a.h>
#include <stdio.h>
#include <delay.h>
int TPS_V;//напряжение в вольтах
char TPS_duty[17] = {0,30,70,100,127,150,190,255,255,255,255,255,255,255,255,255,255};
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
}
#define ADC_VREF_TYPE 0x00
// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

void main(void)
{

#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

PORTB=0x3C;
DDRB=0x03;

TCCR0A=0x81;
TCCR0B=0x05;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

GIMSK=0x00;
MCUCR=0x00;

TIMSK0=0x02;

ACSR=0x80;
ADCSRB=0x00;
DIDR0=0x00;

DIDR0&=0x03;
DIDR0|=0x00;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x84;

#asm("sei")
while (1)
 {

 TPS_V=read_adc(1)>>6; //аналогично делению на 64. Переводим 10 бит АЦП в 4 Бит
 OCR0A=TPS_duty[TPS_V];

 }
}

PS. Спасибо огромное за помощь. За сегодня очень многому научился!

Изменено пользователем ukr823f
Ссылка на комментарий
Поделиться на другие сайты

Необязательно делить, это сильно нагружает МК. Достаточно считать с точностью до 500 об/мин.

Любой массив - линейная последовательность данных в памяти. В Вашем случае двумера столбец умножается на строку и получается адрес ячейки, содержащей требуемое значение.

Вот про это можно подробнее?

Я так и не понял как умножить индекс столбца на индекс строки и получить адрес ячейки. Мне нужно значение допучтим из 3 столбца 3 строки. Если перемножить - то получиться получается 9. А если считать по порядку = то поличиться что нам нужна 21ая ячейка

Изменено пользователем ukr823f
Ссылка на комментарий
Поделиться на другие сайты

Грубо говоря, двумерный массив 4x4 расположен в памяти так [0,0] [0,1] [0,2] [0,3] [1,0] [1,1] [1,2] [1,3] [2,0] [2,1] [2,2] [2,3] [3,0] [3,1] [3,2] [3,3]. Соответственно, чтобы достать элемент, например, [2,3], нужно брать по адресу 2*4+3.

В общем случае, если из массива MxN нужно достать элемент с индексом i,j, адрес будет i*M+j. Все это для абстрактного представления, в реальности надо учитывать что идет по порядку, строки или столбцы, какой размер элемента и т.д.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...