Помогите разобраться с двух мерными массивами

Looka
Offline
Зарегистрирован: 24.04.2012

Собственно вот упрощенный скетч, не могу разобраться почему ошибка.
Идея собственно проста.  Есть класс, объекту которого надо передать для работы таблицу символов, в данном случае это  6 строк по 5 элементов в каждой, в классе толькоуказатель на эту таблицу.  В примере просто печать этой таблицы.
Как сам понимаю компилятору должно быть все равно сколько строк, главное что бы он знал сколько элементов в строке, что бы правильно трактовать  элемент table[x][y]   (строка х, элемнт в это строке у).  Ан нет, ругается зараза..... 

class MyLCD
{  byte *_table[5];
   byte _x, _y;     
   public:  
   MyLCD(int x=84, int y=46 )   { _x=x; _y=y;  }
   void setTable( byte *t[5] )  { _table = t; } 
   void printTable( void ) 
   {  for( int i=0; i<6; i++ )
      for( int j=0; j<5; j++ ) Serial.println( _table[i][j] ); 
   }
};


byte table[6][5] =
{  
   { 0x00, 0x01, 0x02, 0x03, 0x04 },
   { 0x10, 0x11, 0x12, 0x13, 0x14 },
   { 0x20, 0x21, 0x22, 0x23, 0x24 },
   { 0x30, 0x31, 0x32, 0x33, 0x34 },
   { 0x40, 0x41, 0x42, 0x43, 0x44 },
   { 0x50, 0x51, 0x52, 0x53, 0x54 },
}; //

MyLCD cl(24,36);

void setup() {
  // put your setup code here, to run once:
   
  Serial.begin(9600);
  cl.setTable( table );
  cl.printTable();

} // end setup


void loop() 
{  // put your main code here, to run repeatedly: 
  
}  // end loop()

И собственно вот так ругается...


sketch_feb06b.ino: In member function 'void MyLCD::setTable(byte**)':
sketch_feb06b:7: error: incompatible types in assignment of 'byte**' to 'byte* [5]'
sketch_feb06b.ino: In function 'void setup()':
sketch_feb06b:35: error: no matching function for call to 'MyLCD::setTable(byte [6][5])'
sketch_feb06b.ino:7: note: candidates are: void MyLCD::setTable(byte**)

 

ites
Offline
Зарегистрирован: 26.12.2013

Looka пишет:

Собственно вот упрощенный скетч, не могу разобраться почему ошибка.
Идея собственно проста.  Есть класс, объекту которого надо передать для работы таблицу символов, в данном случае это  6 строк по 5 элементов в каждой, в классе толькоуказатель на эту таблицу.  В примере просто печать этой таблицы.
Как сам понимаю компилятору должно быть все равно сколько строк, главное что бы он знал сколько элементов в строке, что бы правильно трактовать  элемент table[x][y]   (строка х, элемнт в это строке у).  Ан нет, ругается зараза..... 

byte (*_table)[5];

 

Looka
Offline
Зарегистрирован: 24.04.2012

Спасибо!

iitusnik
Offline
Зарегистрирован: 09.02.2014

Здравствуйте

Подскажите, пожалуйста, не один час уже голову ломаю. Не могу найти максимальный элемент в двумерном массиве.

Суть такова:

При различных параметрах t 10 раз вызывается процедура udar, совершающая определенные действия. Результаты ее выполнения сохраняются в массив test (первые 20 значений). Далее я ищу максимальный элемент в каждой из 10 строк (т.е. максимальный элемент в каждом эксперименте) и сохраняю его в одномерный массив maxArr. Вот где-то тут ошибка-что-то ему не нравится. Все эти операции происходят по условию, но даже при выполнении условия, описанные мною действия не выполняются (что-то не так в поиске максимума, видимо)

int test[10][20];
float t=0.5;
for (int i=0;i<10;i++)
      {   
        t=t+0.5;
        //Удар (вызов процедуры)
        udar(voltage, t, i);
        //сэйвим значения в массив
        for (int j=0;j<20;j++)
        { 
          test[i][j]=analogRead(sensePin);    
          delay(50);
        } 
      }

int maxA=0;
int maxArr[10];
int maxInd=0;

//-------------->
//    где-то здесь ошибка
for (int i=0;i<10;i++)
      {
        maxA=test[i][0];
        for (int k=1;k<20;k++)
        {
          if (test[i][k] > maxA) 
          {
            maxA=test[i][k]; 
          }         
        }    
        maxArr[i]=maxA;
      }
//<-----------------

maxA=maxArr[0];
maxInd=0;
for (int i=1;i<10;i++)
      {
        if (maxArr[i]>maxA)
        {
          maxA=maxArr[i];
          maxInd=i;
        }
      }

 

Если не совсем понятно объяснил, то, возможно, с полным скетчем будет понятнее. Если закомментить поиск максимума в двумерном массиве-то хотя бы заходит в условие  if(strSMS == "2"), иначе оно просто игнорируется. На смски потратил уже рублей 100, а толку нет. Подскажите, пожалуйста, что не так


#include <GSM.h>
#include <avr/pgmspace.h>
#include <OneWire.h>  //подключаем библиотеку

//CosmoGSM использует ноги
//цифровые: 0, 1, 6, 7
//аналоговые: 2, 3 (если включен режим RTS и CTS) 

const char RemoteID[] PROGMEM =  "+7910xxxxxxx"; //Шаблон номера, с которого ждём звонка и на который отправляем СМС
const char PIN[] PROGMEM =  "0000"; //ПИН-код
char SMStxt[162]; // Буфер для чтения текста СМС
String strSMS;
unsigned long interval = 60000; //Интервал проверки состояния GPRS соединения
unsigned long currentMillis;
unsigned long previousMillis;

//Пины мотора
int motorPinLeft=9;  //Крутится влево
int motorPinRight=10;  //Крутится вправо

OneWire  ds(2);  // Номер ноги к которой подключили датчик температуры
int sensePin=0;  //Sound

void setup() 
{
  delay(4000);
  while (GSM.Init(PIN)<0);
  GSM.NewSMSindic();
  GSM.WaitCall();    
  GSM.WaitSMS();
  previousMillis=millis();

  pinMode (motorPinLeft, OUTPUT);
  pinMode (motorPinRight, OUTPUT);
}

//===================================================
//                        LOOP                     //
//===================================================
void loop() 
{        
  analogWrite (motorPinLeft, 0);
  delay(500);
  analogWrite (motorPinRight, 0);
  delay(500); 

  // Начало отсчёта 60 сек.       
  currentMillis = millis();
  if (GSM.CheckSMS()== 1) 
  { 
    //Есть новое СМС
    GSM.ReadSMS(NewSMS_index, (char*) SMStxt); //
    // Удалить СМСки (накапливать не будем!)
    GSM.DeleteAllSMS();
    strSMS = String(SMStxt);

    //Получаем смс

    //Если пришла 1
    if(strSMS == "1") 
    { 
      //вызов функции, возвращающей
      //значение температуры
      float celsius = TemperatureFunction();

      //переводим полученное значение
      //температуры в массив символов и передаем
      char temperature[20];
      floatToString(temperature, celsius, 2, 7);

      while(GSM.SendSMS(RemoteID, temperature) < 0);
    }

    //Если пришла 2
    else if(strSMS == "2") 
    {     
      while(GSM.SendSMS(RemoteID, "ok") < 0);
      float TestArr[10][2]; //массив из 10 столбцов (10 опытов),хранящий параметры ударов
      int test[10][20];
      float t=0.5;
      float voltage=51;

      for (int i=0;i<10;i++)
      {   
        TestArr[i][0]=t+0.5;
        TestArr[i][1]=voltage;
      }
      //Совершаем 10 ударов и берем по 20 значений амплитуды 
      t=0.5;
      for (int i=0;i<10;i++)
      {   
        t=t+0.5;
        //Удар (вызов процедуры)
        udar(voltage, t, i);
        //сэйвим значения в массив
        for (int j=0;j<20;j++)
        { 
          test[i][j]=analogRead(sensePin);    
          delay(50);
        } 
        //       delay(10000); //даем звуку стихнуть и колоколу перестать качаться
      }

      analogWrite (motorPinLeft, voltage*5);//возвращаем вал в нужное положение
      delay(10*t);
      analogWrite (motorPinLeft, voltage*5);//возвращаем вал в нужное положение
      delay(10*t);
      //все по 0
      analogWrite (motorPinLeft, 0);
      delay(500);
      analogWrite (motorPinRight, 0);
      delay(500);

      //Ищем максимальное значение амплитуды звука
      //и определяем параметры этого удара
      int maxA=0;
      int maxArr[10];
      int maxInd=0;

      for (int i=0;i<10;i++)
      {
        maxA=test[i][0];
       
        for (int k=1;k<20;k++)
        {
          if (test[i][k] > maxA) 
          {
            maxA=test[i][k]; 
          }         
        }    
       
        maxArr[i]=maxA;
      }

      maxA=maxArr[0];
      maxInd=0;
      for (int i=1;i<10;i++)
      {
        if (maxArr[i]>maxA)
        {
          maxA=maxArr[i];
          maxInd=i;
        }
      }

      //вывод оптимальных параметров
      char period[20];
      floatToString(period, TestArr[maxInd][0], 2, 7);

      while(GSM.SendSMS(RemoteID, period) < 0);
      delay(20000);   

      GSM.WaitCall();
      GSM.WaitSMS();
      // Начало отсчёта 60 сек.       
      currentMillis = previousMillis = millis();   
    }//Text of SMS        
  }//SMS  
}//loop








//===================================================
//               ПРОЦЕДУРЫ И ФУНКЦИИ               //
//===================================================


//функция для перевода из десятичной дроби в строковый вид
char * floatToString(char * outstr, double val, byte precision, byte widthp)
{
  char temp[16]; //increase this if you need more digits than 15
  byte i;

  temp[0]='\0';
  outstr[0]='\0';

  if(val < 0.0)
  {
    strcpy(outstr,"-\0");  //print "-" sign
    val *= -1;
  }

  if( precision == 0) 
  {
    strcat(outstr, ltoa(round(val),temp,10));  //prints the int part
  }
  else 
  {
    unsigned long frac, mult = 1;
    byte padding = precision-1;

    while (precision--)
      mult *= 10;

    val += 0.5/(float)mult;      // compute rounding factor

    strcat(outstr, ltoa(floor(val),temp,10));  //prints the integer part without rounding
    strcat(outstr, ".\0"); // print the decimal point

    frac = (val - floor(val)) * mult;

    unsigned long frac1 = frac;

    while(frac1 /= 10)
      padding--;

    while(padding--)
      strcat(outstr,"0\0");    // print padding zeros

    strcat(outstr,ltoa(frac,temp,10));  // print fraction part
  }

  // generate width space padding
  if ((widthp != 0)&&(widthp >= strlen(outstr)))
  {
    byte J=0;
    J = widthp - strlen(outstr);

    for (i=0; i< J; i++) {
      temp[i] = ' ';
    }

    temp[i++] = '\0';
    strcat(temp,outstr);
    strcpy(outstr,temp);
  }

  return outstr;
}

//-----------------------------------------------------
//Процедура, выполняющая один удар в колокол
void udar(float voltage, float t, int i)
{  
  analogWrite (motorPinLeft, voltage*5);
  delay(100*t);
  analogWrite (motorPinLeft, 0);
  delay(10);
  analogWrite (motorPinRight, 255);
  delay((20-i*2)*t);
  analogWrite (motorPinRight, 0);
  delay(10);
}

//-----------------------------------------------------
// Получение температуры
float TemperatureFunction()
{
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;

  if ( !ds.search(addr)) 
  {
    while(GSM.SendSMS(RemoteID, "Invalid Adress Of TemperatureDevice") < 0);
    ds.reset_search();
    delay(250);
    goto *loop;
  }

  if (OneWire::crc8(addr, 7) != addr[7]) 
  {
    while(GSM.SendSMS(RemoteID, "CRC is non right!") < 0);
    goto *loop;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);      
  delay(1000);     
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);        

  for ( i = 0; i < 9; i++) 
  {          
    data[i] = ds.read();
  }
  //  Преобразование данных в фактическую температуру
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) 
  {
    raw = raw << 3; 
    if (data[7] == 0x10) 
    {
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } 
  else 
  {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw & ~7;  
    else if (cfg == 0x20) raw = raw & ~3;
    else if (cfg == 0x40) raw = raw & ~1; 
  }
  celsius = (float)raw / 16.0;

  return celsius;
}


//-----------------------------------------------------
// Функция настройки
int SetupFunction()
{
  int i;
  int j;
  int test[10][20];
  //параметры удара
  float voltage=51;
  float t=0.5;

  //Совершаем 10 ударов и берем по 20 значений амплитуды
  for (i=0;i<10;i++)
  {   
    t=t+0.5;

    //Удар (вызов процедуры)
    udar(voltage, t, i);

    //сэйвим значения в массив
    // с 3 по n-1 ячейку включительно (n-2 значений/опыт)
    for (j=0;j<20;j++)
    { 
      test[i][j]=analogRead(sensePin);    
      delay(50);
    } 
    delay(10000); //даем звуку стихнуть и колоколу перестать качаться  
  }

  while(GSM.SendSMS(RemoteID, "rrr") < 0);

  analogWrite (motorPinLeft, voltage*5);//возвращаем вал в нужное положение
  delay(10*t);

  //все по 0
  analogWrite (motorPinLeft, 0);
  delay(500);
  analogWrite (motorPinRight, 0);
  delay(500);

  //Ищем максимальное значение амплитуды звука
  //и определяем параметры этого удара
  int maxA=0;
  int maxArr[10]; 
  int maxInd;    

  for (i=0;i<10;i++)
  {
    for (j=0;j<20;j++)
    {
      if (test[i][j]>maxA)
      {
        maxA=test[i][j];   
      }
    }
    maxArr[i]=maxA;
  }

  maxA=maxArr[0];
  maxInd=0;
  for (i=1;i<10;i++)
  {
    if (maxArr[i]>maxA)
    {
      maxA=maxArr[i];
      maxInd=i;
    }
  } 

  return maxInd;  
}

//-----------------------------------------------------