Указатели на функции?

Starpom
Offline
Зарегистрирован: 06.03.2011

Есть ли в Arduino, указатели на функции? Если есть, то если не затруднит, любой пример.

Adessit
Adessit аватар
Offline
Зарегистрирован: 12.04.2011

Перед loop()

пишем саму функцию void arduinoru(X){код функции например над переменной Х++ и вывод на какой-то порт её}

Потом в самом loop() {

.....

текст программы создающая переменную Y, а дальше вызываем саму функцию и выдаём ей эту переменную Y

......

arduinoru(Y);

Nikelbak
Nikelbak аватар
Offline
Зарегистрирован: 22.03.2011

Можно и после loop(), помоему об этом чтото есть в разделе программирование

San4eS
Offline
Зарегистрирован: 02.05.2011

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

 

void start(char* p) {
 Serial.println(p);
}

void (*Write)(char*);

void setup()
{
  Serial.begin(9600);
  Write = &start;
  (*Write)("I've started, yeah! :)");
}

void loop()
{  
}

При этом void (*Write)(char*); - сам указатель на функцию

San4eS
Offline
Зарегистрирован: 02.05.2011

Adessit пишет:

Перед loop()

пишем саму функцию void arduino.ru(X) ...

Никогда не заработает - в имени функции нельзя использовать никаких символов кроме a..z A..Z 0..9 и символа подчёркивания, при этом цифра не может быть первым символом названия функции.

Adessit
Adessit аватар
Offline
Зарегистрирован: 12.04.2011

это был пример. Сейчас исправлю. Спасибо что подправили 

Broker
Offline
Зарегистрирован: 15.04.2011

До поста San4Es  все понятно. 

Пожалуйста расшифруйте :

void
(*Write)(char*);

Почему
Write
в скобках? И для чего * в обоих случаях
?

Cпасибо.

 

San4eS
Offline
Зарегистрирован: 02.05.2011

Broker пишет:

void (*Write)(char*);

Почему Write в скобках? И для чего * в обоих случаях ?

Описание

void (*Write)(char*);

 

говорит, что Write является указателем на функцию, которая возвращает значение типа void и параметр типа char*. Первые круглые скобки здесь необходимы; без них описание

void *Write(char*);

 

говорило бы, что Write является функцией, возвращающей указатель на void, что, конечно, совершенно другая вещь.

Broker
Offline
Зарегистрирован: 15.04.2011

 Спасибо. А есть ли где нибудь об указателях на функции ? На arduino.cc ?

P.S. : Вот прекрасный ресурс для обучения , с конкретными примерами. ( на англ. языке , но все понятно ). 

 http://tronixstuff.wordpress.com/tutorials/

Там и учусь.

 

San4eS
Offline
Зарегистрирован: 02.05.2011

 Указатели на функции и прочее с той же оперы - это, всё-таки, более к программированию и особенностям языка относится. На arduino.cc говориться только об основах и более апаратно-привязаных вещах. Ищите справочники по С..

Broker
Offline
Зарегистрирован: 15.04.2011

 Теперь понятно почему мне не приходилось, до сих пор, сталкиваться с такой конструкцией. Пасиб.  

Iwan73
Offline
Зарегистрирован: 02.11.2013

Подскажите пожалуйста,изучая библиотеку leOS ,пытаюсь создать указатель на функцию возвращающую значение unsigned char,выдает при проверке

invalid conversion from void(*)() to uint8_t(*)()

в самой бибе исправление внес, было    

typedef void (*voidFuncPtr)(void);

void (*voidFuncPtr)(void);

изменил на

 typedef uint8_t (*voidFuncPtr)(void);

uint8_t (*voidFuncPtr)(void);

ну и в функциях поправил. Все равно то же самое. вот скетч


#include <leOS.h>
#include <PCF8814.h>

#define BattaryPin   A2
unsigned char Zarjad=0;// уровень заряда батареи
leOS myOS;
PCF8814 Lcd(13,11,10,9);// LCD set SCLK: 13 pin, SDA: 11 pin, CS: 10pin, RESET: 9 pin
//------ измерение уравня заряда по напряжению -----------------
unsigned char Read_Batary()
{
  unsigned int BattaryValue=0;
  BattaryValue = analogRead(BattaryPin);
    if (BattaryValue<745)//напряжение меньше 3.6в  -0%
  {
    Zarjad=0; 
  }
  if (BattaryValue >= 750 && BattaryValue < 765)//напряжение 3.6в и меньше 3.72 -10%
  {
    Zarjad=1;
  }
  if (BattaryValue >= 775 && BattaryValue < 780)// напряжение 3.72в и меньше 3.84- 20%
  {
    Zarjad=2;
  }
  if (BattaryValue >= 800 && BattaryValue < 815 )// напряжение 3.84в и меньше 3.96- 40%
  {
    Zarjad=3;
  }
  if (BattaryValue >= 825 && BattaryValue < 840 )// напряжение 3.96в и меньше 4.08- 60%
  {
    Zarjad=4;
  }
  if (BattaryValue >= 850  && BattaryValue < 865 )// напряжение 4.08в и меньше 4.2- 80%
  {
    Zarjad=5;
  }
  if (BattaryValue > 865 && BattaryValue >= 875)// напряжение 4.2в и больше-100%
  {
    Zarjad=6;
  }
  return Zarjad;
}
//------ рисуем батарейку и уровни заряда --------------------------
void Image_Batary()
{
  Lcd.Rect (78,0, 95, 9, FILL_OFF, PIXEL_ON);// основа батарейки
  Lcd.Rect (75,2, 78, 7, FILL_OFF, PIXEL_ON);// пимпочка
  Lcd.Line (78,3, 78,6, PIXEL_OFF);//стираем перемычку
}

void Zarjad_10()
{
  Lcd.Rect (92,2, 93, 7, FILL_ON,PIXEL_ON);// 6 деление 10%
}

void Zarjad_20()
{
  Zarjad_10();
  Lcd.Rect (89,2, 90, 7, FILL_ON,PIXEL_ON);// 5 деление 20%
}

void Zarjad_40()
{
  Zarjad_20();
  Lcd.Rect (86,2, 87, 7, FILL_ON,PIXEL_ON);// 4 деление 40%
}

void Zarjad_60()
{
  Zarjad_40();
  Lcd.Rect (83,2, 84, 7, FILL_ON,PIXEL_ON);// 3 деление 60%
}

void Zarjad_80()
{
  Zarjad_60();
  Lcd.Rect (80,2, 81, 7, FILL_ON,PIXEL_ON);// 2 деление 80%
}

void Zarjad_Full()
{
  Zarjad_80();
  Lcd.Rect (77,4, 78, 5, FILL_ON,PIXEL_ON);// 1 деление 100%
}

uint8_t(*pImage_Batary)();//указатель на функцию
 
void setup() {
pinMode(BattaryPin, INPUT);
pImage_Batary = Image_Batary;
 myOS.begin();
}

void loop() {
  myOS.addTask_R(pImage_Batary, 1000);
}

с указателями на функцию столкнулся в первый раз. 

leshak
Offline
Зарегистрирован: 29.09.2011

Iwan73 пишет:

invalid conversion from void(*)() to uint8_t(*)()

Где-то что-то не доменяли. И никто вам не поможет, так как только вы знаете ГДЕ выскакивает эта ошибка. Там же должна быть строка (только внимательно, нужно искать именно начало стека ошибок, а не его вершину). Смотрите кого оно пытается конвертировать. Кто там, на самом деле оказался void(*)(). Потом смотрите где этот "кто-то" объявлен. Как он объявлен и т.д.
Вы просто не забивайте себя страхом что это "указатели". В данном случае это ничем не отличается от "просто тип такой". Работайте с этим как будтно вы решили помеять, скажем тип переменной с char на unsigned long и у вас начала выскакивать ошибка "invalid conversion from char to unsigned long". Просто искать где-же этот чертов char остался :)

San4eS
Offline
Зарегистрирован: 02.05.2011

У Вас Image_Batary возвращает void, при этом указатель на функцию возвращает uint8_t. Соответственно присвоить второму первое нельзя. Вероятно Вы хотели в таск закинуть ReadBatary, хотя я не вижу никакой логики в этих действиях. Все что Вы хочете сделать делается елементарно без смены библиотеки

San4eS
Offline
Зарегистрирован: 02.05.2011

Вот примерно так можно сделать не изменяя библиотеку:

#include <leOS.h>
#include <PCF8814.h>

#define BattaryPin   A2
unsigned char Zarjad=0;// уровень заряда батареи
leOS myOS;
PCF8814 Lcd(13,11,10,9);// LCD set SCLK: 13 pin, SDA: 11 pin, CS: 10pin, RESET: 9 pin

//------ рисуем батарейку и уровни заряда --------------------------
void Image_Batary()
{
  Lcd.Rect (78,0, 95, 9, FILL_OFF, PIXEL_ON);// основа батарейки
  Lcd.Rect (75,2, 78, 7, FILL_OFF, PIXEL_ON);// пимпочка
  Lcd.Line (78,3, 78,6, PIXEL_OFF);//стираем перемычку
}

void Zarjad_10()
{
  Lcd.Rect (92,2, 93, 7, FILL_ON,PIXEL_ON);// 6 деление 10%
}

void Zarjad_20()
{
  Zarjad_10();
  Lcd.Rect (89,2, 90, 7, FILL_ON,PIXEL_ON);// 5 деление 20%
}

void Zarjad_40()
{
  Zarjad_20();
  Lcd.Rect (86,2, 87, 7, FILL_ON,PIXEL_ON);// 4 деление 40%
}

void Zarjad_60()
{
  Zarjad_40();
  Lcd.Rect (83,2, 84, 7, FILL_ON,PIXEL_ON);// 3 деление 60%
}

void Zarjad_80()
{
  Zarjad_60();
  Lcd.Rect (80,2, 81, 7, FILL_ON,PIXEL_ON);// 2 деление 80%
}

void Zarjad_Full()
{
  Zarjad_80();
  Lcd.Rect (77,4, 78, 5, FILL_ON,PIXEL_ON);// 1 деление 100%
}


//------ измерение уравня заряда по напряжению -----------------
void Read_Batary()
{
  unsigned int BattaryValue=0;
  BattaryValue = analogRead(BattaryPin);
  Image_Batary();
  if (BattaryValue<745)//напряжение меньше 3.6в  -0%
  {
    Zarjad=0; 
  } else if (BattaryValue >= 746 && BattaryValue < 765)//напряжение 3.6в и меньше 3.72 -10%
  {
    Zarjad=1;
	Zarjad_10();
  } else if (BattaryValue >= 766 && BattaryValue < 780)// напряжение 3.72в и меньше 3.84- 20%
  {
    Zarjad=2;
	Zarjad_20();
  } else if (BattaryValue >= 781 && BattaryValue < 815 )// напряжение 3.84в и меньше 3.96- 40%
  {
    Zarjad=3;
	Zarjad_40();
  } else if (BattaryValue >= 816 && BattaryValue < 840 )// напряжение 3.96в и меньше 4.08- 60%
  {
    Zarjad=4;
	Zarjad_60();
  } else if (BattaryValue >= 841  && BattaryValue < 865 )// напряжение 4.08в и меньше 4.2- 80%
  {
    Zarjad=5;
	Zarjad_80();
  } else // напряжение 4.2в и больше-100%
  {
    Zarjad=6;
	Zarjad_Full();
  }
}

void(*pRead_Batary)();//указатель на функцию
 
void setup() {
	pinMode(BattaryPin, INPUT);
	pRead_Batary = &Read_Batary;
	myOS.begin();
}

void loop() {
  myOS.addTask_R(pRead_Batary, 1000);
  // или так
  // myOS.addTask_R(&Read_Batary, 1000);
}

 

Iwan73
Offline
Зарегистрирован: 02.11.2013

Большое спасибо всем,разобрался теперь.