Qual a linguagem usada no código?

Boa noite a todos

Sou novo nestas andanças, será que poderiam ajudar a descobrir qual a linguagem usada no código em baixo.
Não me parece ser nem Arduino, nem Processing, nem C++ ou antes é parecida com as três só que tem uma escrita estranha, tal com → ou :: e corre no IDE do Arduino…
É o projecto “Knock box (it opens when you knock on it!)” do site Instructables - http://www.instructables.com/id/Knock-box-it-opens-when-you-knock-on-it/?lang=pt
e eu queria realizar este projeto mas também queria perceber o código.

Se me poderem ajudar, agradeço.

/************************************/
/************ KNOCK BOX *************/
/*** A project by Michele Marolla ***/
/************************************/
 
#include <Servo.h>
 
/* Pins */
const int closedLED_p = 5;
const int openLED_p = 6;
const int inputLED_p = 7;
const int rhythmBTN_p = 8;
const int closeBTN_p = 9;
const int playBTN_p = 10;
const int piezo_p = A0;
const int servo_p = 11;
 
 
/* Rhythm Management */
const int RHYTHM_SIZE = 10;
const int TOLERANCE = 150;
const int TRESHOLD = 20;
class Rhythm{
  private:
    int rhythm[RHYTHM_SIZE];
 
  public:
    Rhythm();
    void getRhythm(int *rhythm_a);
    void setRhythm(const int rhythm_a[RHYTHM_SIZE]);
    int getActualSize() const;
    int getActualSize(const int rhythm_a[RHYTHM_SIZE]) const;
    void play() const;
    void play(const int rhythm_a[RHYTHM_SIZE]) const;
    int listenForKnock() const;
    void listenForRhythm(int *rhythm_a);
    boolean checkRhythm();
   
};
 
Rhythm::Rhythm(){
  int temp[RHYTHM_SIZE] = {500, 500, 100, -1, -1, -1, -1, -1, -1, -1};
  this->setRhythm(temp);
}
 
void Rhythm::getRhythm(int *rhythm_a){
  for(int i=0; i<RHYTHM_SIZE; i++)
    rhythm_a[i] = this->rhythm[i];
}
 
void Rhythm::setRhythm(const int rhythm_a[RHYTHM_SIZE]){
  for(int i=0; i<RHYTHM_SIZE; i++)
    this->rhythm[i] = rhythm_a[i];
}
 
int Rhythm::getActualSize() const{
  return this->getActualSize(this->rhythm);
}
 
int Rhythm::getActualSize(const int rhythm_a[RHYTHM_SIZE]) const{
  int count = 0;
  for(int i=0; i<RHYTHM_SIZE; i++){
    if(rhythm_a[i] == -1)
      break;
    count++;
  }
  return count;
}
 
void Rhythm::play() const{
  this->play(this->rhythm);
}
 
void Rhythm::play(const int rhythm_a[RHYTHM_SIZE]) const{
  pinMode(piezo_p, OUTPUT);
 
  // First knock
  tone(piezo_p, 2000); delay(100); noTone(piezo_p);
 
  // Other knocks
  for(int i=0; i<this->getActualSize(rhythm_a); i++){
    delay(rhythm_a[i]);
    tone(piezo_p, 2000); delay(100); noTone(piezo_p);
  }
}
 
int Rhythm::listenForKnock() const{
  Serial.println("LISTEN FOR KNOCK");
 
  pinMode(piezo_p, INPUT);
  unsigned long time = millis();
  unsigned long temp;
  while(true){
    temp = millis() - time;
    if(temp >= 3000)
      return -1;
    if((analogRead(piezo_p) >= TRESHOLD) && (temp >= 100)){
      digitalWrite(inputLED_p, HIGH);
      delay(20);
      digitalWrite(inputLED_p, LOW);
      return (int)temp;
    }
    delay(50);
  }
}
 
void Rhythm::listenForRhythm(int *rhythm_a){
  int time;
  this->listenForKnock(); // First knock
  int i;
  for(i=0; i<RHYTHM_SIZE; i++){
    time = this->listenForKnock();
    if(time == -1)
      break;
    rhythm_a[i] = time;
  }
  for(; i<RHYTHM_SIZE; i++)
    rhythm_a[i] = -1;
}
 
boolean Rhythm::checkRhythm(){
  Serial.println("CHECK RHYTHM");
 
  int time;
 
  // Listen and check
  int temp = this->listenForKnock();
  while(temp == -1)
    temp = this->listenForKnock(); // First knock
   
  for(int i=0; i<this->getActualSize(); i++){
    time = this->listenForKnock();
    if((time == -1) || (time > 3000))
      return false;
    if((time < this->rhythm[i]-TOLERANCE)
      || (time > this->rhythm[i]+TOLERANCE))
      return false;
  }
  return true;
}
 
/* Box Management */
class Box{
  private:
    boolean locked;
    Servo servo;
   
  public:
    Box();
    boolean isLocked() const;
    void openBox();
    void closeBox();
    void recordNewRhythm(Rhythm *rhythm);
};
 
Box::Box(){
  this->locked = true;
  this->servo.attach(servo_p);
  this->servo.write(90);
  digitalWrite(openLED_p, LOW);
  digitalWrite(inputLED_p, LOW);
  digitalWrite(closedLED_p, HIGH);
}
 
boolean Box::isLocked() const{
  return this->locked;
}
 
void Box::openBox(){
  this->locked = false;
  this->servo.write(0);
  digitalWrite(openLED_p, HIGH);
  digitalWrite(inputLED_p, LOW);
  digitalWrite(closedLED_p, LOW);
}
 
void Box::closeBox(){
  this->locked = true;
  this->servo.write(90);
  digitalWrite(openLED_p, LOW);
  digitalWrite(inputLED_p, LOW);
  digitalWrite(closedLED_p, HIGH);
}
 
void Box::recordNewRhythm(Rhythm *rhythm){
  digitalWrite(openLED_p, HIGH);
  digitalWrite(closedLED_p, HIGH);
 
  int newRhythm[RHYTHM_SIZE];
  rhythm->listenForRhythm(&newRhythm[0]);
  rhythm->play(newRhythm);
  while(true){
    if(digitalRead(closeBTN_p) == HIGH){
      digitalWrite(closedLED_p, LOW);
      delay(100);
      return;
    }else if(digitalRead(rhythmBTN_p) == HIGH){
      rhythm->setRhythm(newRhythm);
      this->closeBox();
      return;
    }
    delay(100);
  }
}
 
/* Setup */
Box *box;
Rhythm *rhythm;
 
void setup(){
  Serial.begin(9600);
 
  pinMode(closedLED_p, OUTPUT);
  pinMode(openLED_p, OUTPUT);
  pinMode(inputLED_p, OUTPUT);
  pinMode(rhythmBTN_p, INPUT);
  pinMode(closeBTN_p, INPUT);
  pinMode(piezo_p, INPUT);
  pinMode(playBTN_p, INPUT);
 
  box = new Box();
  rhythm = new Rhythm();
}
 
/* Loop */
void loop(){
  Serial.print("Box is locked? ");
  Serial.println(box->isLocked());
 
  if(box->isLocked()){
    if(rhythm->checkRhythm()){
      box->openBox();
    }else{
      tone(piezo_p, 500);
      delay(200);
      noTone(piezo_p);
    }
  }else{
    if(digitalRead(closeBTN_p) == HIGH)
      box->closeBox();
    else if(digitalRead(rhythmBTN_p) == HIGH)
      box->recordNewRhythm(rhythm);
    else if(digitalRead(playBTN_p) == HIGH)
      rhythm->play();
  }
  delay(100);
}

A mim parece-me C++. A tal "escrita estranha" é normal em C++. Por exemplo, o "::" é usado na definição dos métodos das classes. Se procurar nas bibliotecas do seu IDE vai encontrar muitas coisas dessas. Sendo assim, este ficheiro para além de ser um sketch de Arduino, também define a class "Rhythm". Seria também possível criar uma biblioteca com esta class e deixar neste ficheiro pouco mais que o setup() e o loop().

Muito obrigado! Parece ser essa a resposta. Depois de consultar o livro "Programação em C++-Conceitos Básicos e Algoritmos" verifiquei que o operador "->" é aplicado sobre estruturas ou classes e que "::" também. Aproveito para fazer mais perguntas pois parece-me que entende de Arduino e elas são: -Posso programar o Arduino UNO em linguagem C++? Tenho que fazer adaptações? E Processing também posso? Também tenho que fazer adaptações? Obrigado pela resposta.

o operador "->" e usado em apontadores de estruturas... nao e so em C++ que existe.

O Arduino e programado em C++... podes programar em C tambem se preferires, mas muitas das bibliotecas nao vao estar disponiveis. Se por Arduino de referes a placa em si, entao as opcoes aumentam ainda mais e podes programar em Assembly, BASIC e se nao me engano ate PASCAL.

Nao faco ideia acerca do Processing... talvez num site sobre processing te consigam responder a isso.

Que adaptacoes te estas a referir?

As adaptações de C++ que me estou a referir para programar a placa de arduino é por exemplo a instrução *cout<<“Hello World”; * que no IDE Borland C++ imprime o que está entre aspas mas que na placa arduino uno tem que ser substituído por Serial.print(“Hello World”);. Ou seja, a placa arduino uno não corre todas as instruções do C++.

Nao e substituicao... A porta serie do microcontrolador e controlada atraves do objecto Serial... Sao plataformas completamente diferentes e como tal e dificil de fazer exactamente a mesma coisa.

Dito isto, podes usar o printf em vez de Serial.print()... mas nao e de todo a maneira mais eficiente de o fazer.

Por favor, pode indicar-me um livro ou um manual que me ensine a programar a placa arduino uno em C++ usando o IDE (plataforma?) do arduino uno?

Obrigado!

Eu penso que não é necessário nenhum livro, porque há bastante material gratuito na internet. Basta "perder algum tempo" a procurar.

Muito obrigado!
Mas ainda mais uma pergunta. Porque é que o seguinte programa escrito em C++ não corre no IDE do arduino uno?

#include <iostream.h>

int main () {
  cout  << "Hello, World!";
  return 0;
}

Porque o IDE do Arduino não tem a biblioteca iostream.h. Basicamente, porque o Arduino não tem teclado nem monitor, talvez assim se perceba melhor. Também, porque para facilita as coisas aos iniciantes, a função main() já está escrita noutro ficheiro e em C/C++ apenas se pode ter uma função main().

Digamos que a função main(), no arduino, se decompõe em void setup() e void loop()? E não se pode utilizar a função?

Sim, basicamente é isso. No ficheiro “\Arduino\hardware\arduino\avr\cores\arduino\main.cpp” existe este código:

#include <Arduino.h>

//Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (*func)()) { return 0; }

// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }

int main(void)
{
	init();

	initVariant();

#if defined(USBCON)
	USBDevice.attach();
#endif
	
	setup();
    
	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}
        
	return 0;
}

Aqui, é definida a função main() e dentro desta estão, entre outras, as chamadas da função setup() (fora do ciclo principal) e a função loop() (dentro do ciclo).

Sendo assim, se já existe uma função main(), já não pode ser definida outra.
Se quiser “passar por cima” destas definições vai ter que arranjar outro IDE lhe permita fazer isso, mas na minha modesta opinião, não lhe traz vantagem nenhuma, antes pelo contrário vai ter muitos mais problemas, principalmente se for principiante, como parece. Para além de tudo isto, vai continuar a não ter acesso às funções da linguagem C/C++ para controlo do teclado e do ecrã, porque no Arduino não existem.

Obrigado! Acho que tenho uma grande caminhada pela frente...

Eu estava a tentar perceber como poderia aplicar o que aprender no livro "Programação em C++-Conceitos Básicos e Algoritmos" na programação do arduino uno pois este é programável em C++.

Isso é uma pergunta difícil. Em princípio, tudo excepto estas 2 coisas que falámos: - main() - entrada/saída de dados.

No entanto, eu diria que são 2 mundos diferentes e se o que quer é programar em Arduino e não tem muitas bases, convinha ir directamente para aí e não perder muito tempo com o resto. Por exemplo, uma coisa tão simples em "C/C++ para PC" como é ler um número que é introduzido através do teclado, aqui pode ser uma coisa bastante mais complexa. Porquê? Porque este tipo de plataformas não está pensada para isso. Da mesma forma, num PC utilizando C/C++, se quiser ler um sensor de temperatura e ligar uma saída se o valor da temperatura for inferior a um certo nível pode ser bastante complexo.

Eu diria que se está a começar e está a pensar em começar por C++ directamente, até pode nem ser um grande começo. Talvez o melhor seja começar por C e aprender: - como se define uma variável; - o que são vectores e array, e como se definem e acedem; - estruturas de controlo de fluxo (if, if/else, if/else if, switch/case); - estruturas de repetição ou ciclos (while, do/while e for); - estruturas de dados (struct) e criação de tipos definidos pelo utilizador (typedef); - definição e utilização de funções.

A partir daqui é que se pode ir para conceitos mais de alto nível como os utilizados em C++, como: - sobrecarga de operadores; - classes; - objectos; - etc.

Na minha modesta opiniao, tudo depende do proposito.

Se pretende aprender C++, esqueca o Arduino e concentre-se no computador.

Se por outro lado quer mexer com o Arduino, entao o caminho sera primeiro aprender microcontroladores (para entender os numeros magicos que sao usados aqui e ali), depois C e so depois C++ ja que o Arduino da vista do utilizador comum nao faz grande uso do C++ (utilizacao de metodos em vez de funcoes e basicamente a unica coisa que e usada).

Qual e o objectivo? Fazer os exercicios desse livro?

O objectivo é entender programas escritos em C++, como no código que eu apresento na minha primeira intervenção e outros códigos parecidos que aparecem noutros projetos que eu gostava de entender e implementar.

Se o objectivo e aprender C++ eu acho que deves iniciar-te no computador e nao no Arduino. Pura e simplesmente porque historicamente o C/C++ foi criado para programar computadores e so depois adaptado para programar microcontroladores como o Arduino.

Uma prova irrefutavel do C/C++ nao ter sido criado de proposito para microcontroladores e o facto de nao haver suporte nativo para a manipulacao de bits. Em microcontroladores, grande parte das funcoes vao envolver bits, quer seja para activar ou desactivar funcoes/modos, quer seja para escrever ou ler estados de pinos do microcontrolador.

Existem mais comunidades onde podes expor duvidas/problemas que tenhas especificamente a cerca do C++, como o Portugal-a-Programar entre outras que serao mais dedicadas ao que pretendes ja que aqui o foco esta na placa do Arduino.

Nao estou com isto a negar ajuda, apenas a indicar um sitio mais apropriado para questoes relativas a C++.

Desculpem insistir…e voltar à minha primeira pergunta, mas o que devo fazer para perceber o código seguinte que faz parte de um projeto de arduino que eu quero implementar e que está escrito em C++?

/************************************/
/************ KNOCK BOX *************/
/*** A project by Michele Marolla ***/
/************************************/
 
#include <Servo.h>
 
/* Pins */
const int closedLED_p = 5;
const int openLED_p = 6;
const int inputLED_p = 7;
const int rhythmBTN_p = 8;
const int closeBTN_p = 9;
const int playBTN_p = 10;
const int piezo_p = A0;
const int servo_p = 11;
 
 
/* Rhythm Management */
const int RHYTHM_SIZE = 10;
const int TOLERANCE = 150;
const int TRESHOLD = 20;
class Rhythm{
  private:
    int rhythm[RHYTHM_SIZE];
 
  public:
    Rhythm();
    void getRhythm(int *rhythm_a);
    void setRhythm(const int rhythm_a[RHYTHM_SIZE]);
    int getActualSize() const;
    int getActualSize(const int rhythm_a[RHYTHM_SIZE]) const;
    void play() const;
    void play(const int rhythm_a[RHYTHM_SIZE]) const;
    int listenForKnock() const;
    void listenForRhythm(int *rhythm_a);
    boolean checkRhythm();
   
};
 
Rhythm::Rhythm(){
  int temp[RHYTHM_SIZE] = {500, 500, 100, -1, -1, -1, -1, -1, -1, -1};
  this->setRhythm(temp);
}
 
void Rhythm::getRhythm(int *rhythm_a){
  for(int i=0; i<RHYTHM_SIZE; i++)
    rhythm_a[i] = this->rhythm[i];
}
 
void Rhythm::setRhythm(const int rhythm_a[RHYTHM_SIZE]){
  for(int i=0; i<RHYTHM_SIZE; i++)
    this->rhythm[i] = rhythm_a[i];
}
 
int Rhythm::getActualSize() const{
  return this->getActualSize(this->rhythm);
}
 
int Rhythm::getActualSize(const int rhythm_a[RHYTHM_SIZE]) const{
  int count = 0;
  for(int i=0; i<RHYTHM_SIZE; i++){
    if(rhythm_a[i] == -1)
      break;
    count++;
  }
  return count;
}
 
void Rhythm::play() const{
  this->play(this->rhythm);
}
 
void Rhythm::play(const int rhythm_a[RHYTHM_SIZE]) const{
  pinMode(piezo_p, OUTPUT);
 
  // First knock
  tone(piezo_p, 2000); delay(100); noTone(piezo_p);
 
  // Other knocks
  for(int i=0; i<this->getActualSize(rhythm_a); i++){
    delay(rhythm_a[i]);
    tone(piezo_p, 2000); delay(100); noTone(piezo_p);
  }
}
 
int Rhythm::listenForKnock() const{
  Serial.println("LISTEN FOR KNOCK");
 
  pinMode(piezo_p, INPUT);
  unsigned long time = millis();
  unsigned long temp;
  while(true){
    temp = millis() - time;
    if(temp >= 3000)
      return -1;
    if((analogRead(piezo_p) >= TRESHOLD) && (temp >= 100)){
      digitalWrite(inputLED_p, HIGH);
      delay(20);
      digitalWrite(inputLED_p, LOW);
      return (int)temp;
    }
    delay(50);
  }
}
 
void Rhythm::listenForRhythm(int *rhythm_a){
  int time;
  this->listenForKnock(); // First knock
  int i;
  for(i=0; i<RHYTHM_SIZE; i++){
    time = this->listenForKnock();
    if(time == -1)
      break;
    rhythm_a[i] = time;
  }
  for(; i<RHYTHM_SIZE; i++)
    rhythm_a[i] = -1;
}
 
boolean Rhythm::checkRhythm(){
  Serial.println("CHECK RHYTHM");
 
  int time;
 
  // Listen and check
  int temp = this->listenForKnock();
  while(temp == -1)
    temp = this->listenForKnock(); // First knock
   
  for(int i=0; i<this->getActualSize(); i++){
    time = this->listenForKnock();
    if((time == -1) || (time > 3000))
      return false;
    if((time < this->rhythm[i]-TOLERANCE)
      || (time > this->rhythm[i]+TOLERANCE))
      return false;
  }
  return true;
}
 
/* Box Management */
class Box{
  private:
    boolean locked;
    Servo servo;
   
  public:
    Box();
    boolean isLocked() const;
    void openBox();
    void closeBox();
    void recordNewRhythm(Rhythm *rhythm);
};
 
Box::Box(){
  this->locked = true;
  this->servo.attach(servo_p);
  this->servo.write(90);
  digitalWrite(openLED_p, LOW);
  digitalWrite(inputLED_p, LOW);
  digitalWrite(closedLED_p, HIGH);
}
 
boolean Box::isLocked() const{
  return this->locked;
}
 
void Box::openBox(){
  this->locked = false;
  this->servo.write(0);
  digitalWrite(openLED_p, HIGH);
  digitalWrite(inputLED_p, LOW);
  digitalWrite(closedLED_p, LOW);
}
 
void Box::closeBox(){
  this->locked = true;
  this->servo.write(90);
  digitalWrite(openLED_p, LOW);
  digitalWrite(inputLED_p, LOW);
  digitalWrite(closedLED_p, HIGH);
}
 
void Box::recordNewRhythm(Rhythm *rhythm){
  digitalWrite(openLED_p, HIGH);
  digitalWrite(closedLED_p, HIGH);
 
  int newRhythm[RHYTHM_SIZE];
  rhythm->listenForRhythm(&newRhythm[0]);
  rhythm->play(newRhythm);
  while(true){
    if(digitalRead(closeBTN_p) == HIGH){
      digitalWrite(closedLED_p, LOW);
      delay(100);
      return;
    }else if(digitalRead(rhythmBTN_p) == HIGH){
      rhythm->setRhythm(newRhythm);
      this->closeBox();
      return;
    }
    delay(100);
  }
}
 
/* Setup */
Box *box;
Rhythm *rhythm;
 
void setup(){
  Serial.begin(9600);
 
  pinMode(closedLED_p, OUTPUT);
  pinMode(openLED_p, OUTPUT);
  pinMode(inputLED_p, OUTPUT);
  pinMode(rhythmBTN_p, INPUT);
  pinMode(closeBTN_p, INPUT);
  pinMode(piezo_p, INPUT);
  pinMode(playBTN_p, INPUT);
 
  box = new Box();
  rhythm = new Rhythm();
}
 
/* Loop */
void loop(){
  Serial.print("Box is locked? ");
  Serial.println(box->isLocked());
 
  if(box->isLocked()){
    if(rhythm->checkRhythm()){
      box->openBox();
    }else{
      tone(piezo_p, 500);
      delay(200);
      noTone(piezo_p);
    }
  }else{
    if(digitalRead(closeBTN_p) == HIGH)
      box->closeBox();
    else if(digitalRead(rhythmBTN_p) == HIGH)
      box->recordNewRhythm(rhythm);
    else if(digitalRead(playBTN_p) == HIGH)
      rhythm->play();
  }
  delay(100);
}

"Há muitas maneiras de caçar moscas." Porque a pessoa que criou este projecto ter utilizado C++ e ter criado essas classes, não quer dizer que isso seja obrigatório. Fazendo uma pesquisa na maior loja de livros on-line por "Arduino C++", devolve isto, e à primeira vista não aparece nenhum livro de "aprenda a programar Arduino com C++". Aparece sim, qualquer coisa com "aprenda a programar Arduino com C".

A minha sugestão, como disse anteriormente, é se não sabe nada de programação, comece pelos conceitos básicos de C (isso deve tê-lo entretido durante uns bons meses). Após isso, pode evoluir para os conceitos relacionados com C++.