[Résolu - Merci beaucoup :) ] TaskMe - Mon gestionnaire de tâches ménagères

Bonjour à tous,

Je reviens vers vous après avoir avancer sur mon projet.
Je vous le décrit rapidement :
J'ai créer une classe CTask en c++ (Pour apprendre principalement)

Je l'ai ensuite importée dans la bibliothèque de l'IDE d'Arduino et la création d'objet fonctionne. Parfait jusque là !
J'ai ensuite ajouté un écran LCD 16*2. Sur la première ligne on affiche le jour, sur la seconde la tâche à réaliser et par qui elle doit l'être. J'ai également ajouter 2 boutons poussoirs, le premier pour faire défiler les tâches de la journée sur la deuxième ligne et le second pour marquer la tâche affichée comme réalisée, et ainsi affecter cette tâche à quelqu'un d'autre pour les prochains jours.
(J'ai également un module DS1302 pour gérer la date)

Mon problème est le suivant :
Lors des tests, j'ai créé 6 Tâches, et toutes s'affichent correctement sur l'écran :slight_smile:
J'ai alors voulu ajouter toutes les tâches ménagères de la maison, et catastrophe mon écran bug complètement. Après plusieurs tests, j'ai remarqué que le bug arrivait lorsque je crée au moins 12 tâches sur la journée, et je ne comprends absolument pas pourquoi ça ne fonctionne pas... :sob:

Voici mon code, encore un peu brouillon mais fonctionnel pour un nombre limiter de tâches :sweat_smile:

Notes pour gagner du temps dans la lecture :
-Objet CTask possède : Un nom, un temps, une difficulté (pour le tri), une récurrence hebd., une liste de jour sous forme d'entier, et 2 flags pour gérer l'affichage.
-> Flag1 permet de ne pas boucler sur l'affichage de la tâche, j'évite le clignotement.
-> Flag2 permet d'afficher "Done" sur la première ligne si la tâche est effectuée et d'affecter un nouvel individu à cette tâche.

Retirer car nombre maximum de caractère dépassé pour ce post :
Fonction IntDay retourne le jour sous forme d'entier
Fonction FrDay retourne le jour en français

#include <LiquidCrystal.h>
#include<CTask.h>
#include <DS1302.h>
  DS1302 rtc(8, 10, 11);
  int nbtask =12;
  String memoireday;
  // pointeur day
  int* Lundi;
  int* Mardi;
  int* Mercredi;
  int* Jeudi;
  int* Vendredi;
  int* Samedi;
  int* Dimanche;

  int* AllDay;
  int* LMeV;
  
  int Indice=0;
  
  int memoireboutonScroll=1;
  int boutonScroll=9;

  int memoireboutonTask=1;
  int boutonTask=12;
  
  CTask Vaisselle("Vaisselle",1,1);
  CTask PlanDeTravail("Plan travail",1,1);
  CTask Table("Table",1,1);
  CTask Bar("Bar",1,1);
  CTask Balais("Balais",1,2);
  CTask Serpillere("Serpillere",1,2);
  CTask Toilette("Toilette",7,3);
  CTask Douche("Douche",5,2);
  CTask Lavabo("Lavabo",2,1);
  CTask TableBasse("Table basse",4,1);
  CTask Tele("Tele",1,1);
  CTask Tapis("Tapis",10,3);
  CTask PoubelleS("Sortir poubelle",5,3);
  CTask PoubelleR("Rentrer poubelle",5,3);

  CTask* ptask;

  int nbindividu = 2;
  CIndividu William("William");
  CIndividu Adam("Adam");
  CIndividu* Individu;

  // Initalisation de la librairie
  const int rs = 2, en = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
  LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


void setup() {
  
  Serial.begin(9600);
  pinMode(boutonScroll,INPUT_PULLUP);
  pinMode(boutonTask,INPUT_PULLUP);

  // ---------- Time ---------
  rtc.halt(false);
  rtc.writeProtect(false);

  rtc.setDOW(SATURDAY);        // Set Day-of-Week
  //rtc.setTime(20, 52, 10);     // Set the time to 12:00:00 (24hr format)
  //rtc.setDate(3, 18, 2021);   // Set the date to August 6th, 2010*/
  //----------------------------------------
  // ------ Set Up list Day ------
  Lundi=new int;
  *Lundi=0;
  Mardi=new int;
  *Mardi=1;
  Mercredi=new int;
  *Mercredi=2;
  Jeudi=new int;
  *Jeudi=3;
  Vendredi=new int;
  *Vendredi=4;
  Samedi=new int;
  *Samedi=5;
  Dimanche=new int;
  *Dimanche=6;

  LMeV=new int[3];
  LMeV[0]=0;
  LMeV[1]=2;
  LMeV[2]=4;

  AllDay=new int[7];
  for (int i=0;i<7;i++)
  {
    AllDay[i]=i;
  }
  
  // ------ End Set Up list Day ------

  // ------ Set Up TaskDay ------

  Vaisselle.AddDay(1,Samedi);
  PlanDeTravail.AddDay(1,Samedi);
  Table.AddDay(1,Samedi);
  Bar.AddDay(1,Samedi);
  Balais.AddDay(1,Samedi);
  Serpillere.AddDay(1,Samedi);
  Toilette.AddDay(1,Samedi);
  Douche.AddDay(1,Samedi);
  Lavabo.AddDay(1,Samedi);
  TableBasse.AddDay(1,Samedi);
  Tele.AddDay(1,Samedi);
  Tapis.AddDay(1,Samedi);
  //PoubelleS.AddDay(1,Samedi);
  //PoubelleR.AddDay(1,Samedi);
  
  // ------ End Set Up TaskDay ------

    Individu = new CIndividu[nbindividu];
    Individu[0] = William;
    Individu[1] = Adam;

  // ------ ------ Initialisation Task ------ -------

  //if (ptask==NULL)
  //{
    ptask = new CTask[nbtask];
    ptask[0].Copie(Vaisselle);
    ptask[1].Copie(PlanDeTravail);
    ptask[2].Copie(Table);
    ptask[3].Copie(Bar);
    ptask[4].Copie(Balais);
    ptask[5].Copie(Serpillere);
    ptask[6].Copie(Toilette);
    ptask[7].Copie(Douche);
    ptask[8].Copie(Lavabo);
    ptask[9].Copie(TableBasse);
    ptask[10].Copie(Tele);
    ptask[11].Copie(Tapis);
    //ptask[12].Copie(PoubelleS);
    //ptask[13].Copie(PoubelleR);
  //}

    TriTask(ptask,nbtask);
    Attrib(ptask,nbtask,Individu,2);

  lcd.begin(16, 2);
  analogWrite(8,15);
}

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

void loop() {

  if(memoireday!=rtc.getDOWStr())
  {
    for (int i=0;i<nbtask;i++)
    {
      if(ptask[i].Flag2()==false)
      {
        ptask[i].BascFlag2();
      }
    }
  }
  memoireday=rtc.getDOWStr();
  lcd.setCursor(0,0);
  lcd.print(FrDay(rtc.getDOWStr()));
  lcd.print(" : ");

  // Affichage Task du jour
  for (int i=0;i<ptask[Indice].Rec();i++)
  {
    if(ptask[Indice].Day(i)==IntDay(rtc.getDOWStr()) && ptask[Indice].Flag1()==true)
    {
      lcd.setCursor(0,1);
      lcd.print("                ");
      lcd.setCursor(0,1);
      lcd.print(ptask[Indice].TaskName());
      lcd.print(" - ");
      if(ptask[Indice].Flag2()==false) // Si bouton2 a été appuyé
      {
        if (ptask[Indice].Indiv()==Individu[0]) // Valable que pour 2 individus !
        {
          lcd.print(Individu[1].Indiv());
        }
        else
        {
          lcd.print(Individu[0].Indiv());
        }
      }
      else
      {
        lcd.print(ptask[Indice].Indiv());
      } 
      ptask[Indice].BascFlag1(); // Pour que la tâche ne s'affiche qu'une seule fois et pas en boucle 
    }
    int j=FrDay(rtc.getDOWStr()).length()+3;
    if (ptask[Indice].Flag2()==false) // Affichage Done si tâche effectuée
      {
        lcd.setCursor(j,0);
        lcd.print("Done");
      }
      else
      {
        lcd.setCursor(j,0);
        lcd.print("                ");
      }
  }
  int etatboutonScroll = digitalRead(boutonScroll);
  int etatboutonTask = digitalRead(boutonTask);
  if (etatboutonScroll!=memoireboutonScroll && etatboutonScroll==LOW)
  {
    if(ptask[Indice].Flag1()==false)
    {
      ptask[Indice].BascFlag1();
    }
    if (Indice==nbtask-1)                      // ATTENTION BESOIN DU VRAI NOMBRE DE TACHES DE LA JOURNEE !!!
    {
      Indice=0;
      lcd.setCursor(0,1);
      lcd.print("                ");
    }
    else
    {
      Indice++;
    }
      lcd.setCursor(0,1);
      lcd.print("                ");
  }
  if (etatboutonTask!=memoireboutonTask && etatboutonTask==LOW)     // Valable que pour 2 individus !
  {
    ptask[Indice].BascFlag2();
    if(ptask[Indice].Indiv()==Individu[0])
    {
      ptask[Indice].Assign(Individu[1]);
    }
    else
    {
      ptask[Indice].Assign(Individu[0]);
    }
  }
  memoireboutonScroll=etatboutonScroll;
  memoireboutonTask=etatboutonTask;
  Serial.println(ptask[Indice].Indiv());
}
void TriTask(CTask* pT,int n)
{
  for (int i=0;i<n;i++)
  {
    for (int j=i;j<n;j++)
    {
      if(pT[i].Val()>pT[i].Val())
      {
        CTask T(pT[i]);
        pT[i].Copie(pT[j]);
        pT[j].Copie(T); 
      }
    }
  }
}
void Attrib(CTask* ptask,int nT,CIndividu* I,int nI)
{
  int j = 0;
  for (int i = 0; i < nT; i++)
  {
    if (j == nI)
    {
      j = 0;
    }
    ptask[i].Assign(I[j]);
    j++;
  }
}

En espérant que votre sagesse m'éclairera :slight_smile:
Bonne journée

il nous manque le code de la classe CTask pour voir comment vous gérez la mémoire...

et pourquoi tous ces pointeurs avec allocation dynamique ?

int* Lundi;
int* Mardi;
int* Mercredi;
int* Jeudi;
int* Vendredi;
int* Samedi;
int* Dimanche;
...
  Lundi = new int;
  *Lundi = 0;
  Mardi = new int;
  *Mardi = 1;
  Mercredi = new int;
  *Mercredi = 2;
  Jeudi = new int;
  *Jeudi = 3;
  Vendredi = new int;
  *Vendredi = 4;
  Samedi = new int;
  *Samedi = 5;
  Dimanche = new int;
  *Dimanche = 6;

vous pourriez simplement faire

const int lundi = 0;
const int mardi = 1;
...

mais tout ça pour définir des constantes ? faites simplement enum : uint8_t {Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi, Dimanche}; et le compilateur connaîtra les mots clés Lundi, Mardi etc et comme la numérotation d'un enum commence à 0, vous aurez même Lundi qui vaut 0, Mardi 1 etc

En effet je me suis compliqué la vie pour la gestion des jours :cold_sweat:

Voici mon code CTask : (je n'ai pas pu le mettre par manque de place pour le poste).

#pragma once

#include"CIndividu.h"
class CTask
{
protected:
	String m_name;
	CIndividu m_individu;
	int m_difficulty;
	int m_time;
	int m_recurrence;
	int* m_pday;
	bool m_flag1;
	bool m_flag2;

public:
	CTask();
	CTask(String name, int time, int diff);
	CTask(String name, int time, int diff, int rec, int* pday);
	CTask(CTask const&);
	~CTask();

	void Copie(CTask const&);
	int Val();
	void Assign(CIndividu const&);
	String Indiv();
	String TaskName();
	int Rec();
	int Day(int i);
	void AddDay(int rec, int* pday);
	void BascFlag1();
	bool Flag1();
	void BascFlag2();
	bool Flag2();

	friend bool operator!=(CTask, CTask);
	CTask operator=(CTask);
};
#include "CTask.h"

CTask::CTask() : m_name(""), m_individu(),m_difficulty(0),m_time(0),m_recurrence(0),m_pday(NULL),m_flag1(true),m_flag2(true)
{
}

CTask::CTask(String name, int time, int diff,int rec,int* pday)
{
	m_name = name;
	m_time = time;
	m_difficulty = diff;
	m_recurrence = rec;
	m_flag1=true;
	m_flag2 = true;
	m_pday = new int[m_recurrence];
	for (int i = 0; i < m_recurrence; i++)
	{
		m_pday[i] = pday[i];
	}
}

CTask::CTask(String name, int time, int diff)
{
	m_name = name;
	m_time = time;
	m_difficulty = diff;
	m_flag1 = true;
	m_flag2 = true;
}

CTask::CTask(CTask const& T)
{
	m_name = T.m_name;
	m_individu.Copie(T.m_individu);
	m_difficulty = T.m_difficulty;
	m_time = T.m_time;
}

CTask::~CTask()
{
	if (m_pday != NULL)
	{
		delete[] m_pday;
		m_pday = NULL;
	}
}

void CTask::Copie(CTask const& T)
{
	m_name = T.m_name;
	m_individu.Copie(T.m_individu);
	m_difficulty = T.m_difficulty;
	m_time = T.m_time;
	m_recurrence = T.m_recurrence;
	m_pday = new int[m_recurrence];
	m_flag1 = T.m_flag2;
	m_flag2 = T.m_flag2;
	for (int i = 0; i < m_recurrence; i++)
	{
		m_pday[i] = T.m_pday[i];
	}
}

int CTask::Val()
{
	switch (m_difficulty)
	{
	case 1:
		return m_time;
	case 2:
		return m_time + 5;
	case 3:
		return m_time + 10;
	default:
		return -1;
	}
}

void CTask::Assign(CIndividu const& I)
{
	m_individu.Copie(I);
}

String CTask::Indiv()
{
	return m_individu.Indiv();
}

String CTask::TaskName()
{
	return m_name;
}

int CTask::Rec()
{
	return m_recurrence;
}

int CTask::Day(int i)
{
	return m_pday[i];
}

void CTask::AddDay(int rec,int* pday)
{
	m_recurrence = rec;
	m_pday = new int[rec];
	for (int i = 0; i < m_recurrence; i++)
	{
		m_pday[i] = pday[i];
	}
}

void CTask::BascFlag1()
{
	m_flag1 = 1 - m_flag1;
}

bool CTask::Flag1()
{
	return m_flag1;
}

void CTask::BascFlag2()
{
	m_flag2 = 1 - m_flag2;
}

bool CTask::Flag2()
{
	return m_flag2;
}

CTask CTask::operator=(CTask T)
{
	m_name = T.m_name;
	m_individu.Copie(T.m_individu);
	m_difficulty = T.m_difficulty;
	m_time = T.m_time;
	m_recurrence = T.m_recurrence;
	m_pday = new int[m_recurrence];
	for (int i = 0; i < m_recurrence; i++)
	{
		m_pday[i] = T.m_pday[i];
	}
	return *this;
}

bool operator!=(CTask T, CTask P)
{
	if (T.m_name != P.m_name && T.m_difficulty != P.m_difficulty && T.m_time != P.m_time && T.m_recurrence != P.m_recurrence)
	{
		return true;
	}
	else
	{
		return false;
	}
}

il y a des chances pour que ce soit un souci de mémoire disponible au vu de toutes les allocations dynamique que vous effectuez (et vous ne détruisez pas vos copies des String par exemple dans le destructeur)

Un moyen simple de savoir si c'est le souci et si vous avez un Arduino Mega, c'est de faire tourner le code sur le MEGA

Sinon Je trouve que vous allez chercher la difficulté très loin avec toutes ces classes et pointeurs... quelques simples structures permettraient de gérer cela beaucoup plus simplement... De plus il semble que les tâches sont de toutes façons codées en dur dans le code, donc tout cela pourrait être statique, ce qui fait que le compilateur pourrait vous donner exactement la mémoire nécessaire (et ne pas utiliser les String)

J'ai aussi supposé qu'il s'agissait d'un problème de mémoire :slight_smile:
Je n'ai malheureusement pas d'arduino Mega pour vérifier cela et il semble que je n'utilise que 26% de l'espace de stockage et 43% de mémoire dynamique.

Quel genre de structure permettrait de simplifier le programme ?

Merci pour ces réponses :slight_smile:

un exemple "bête" de ce que je veux dire par Structure

enum t_jour : uint8_t {Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi, Dimanche, JourIgnore};
const char* jours[] = {"Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"};

struct t_tache {
  const char * nom;
  const uint8_t duree;
  const uint8_t difficulte;
  bool recurente;
  t_jour jour;
} taches[] = {
  {"Vaisselle", 1, 1, true, Lundi},
  {"Table", 1, 1, true, Samedi },
  {"Bar", 1, 1, true, Mardi },
  {"Balais", 1, 2, true, Samedi },
  {"Serpillere", 1, 2, true, Samedi },
  {"Toilette", 7, 3, true, Samedi },
  {"Douche", 5, 2, true, Lundi },
  {"Lavabo", 2, 1, true, Jeudi },
  {"Table basse", 4, 1, true, Samedi },
  {"Tele", 1, 1, true, Samedi },
  {"Tapis", 10, 3 , true, Samedi },
  {"Sortir poubelle", 5, 3, true, Vendredi },
  {"Rentrer poubelle", 5, 3, true, Samedi }
};
const uint8_t nbTaches = sizeof taches / sizeof taches[0];

struct t_individu {
  const char * nom;
} individus[] = {{"William"},{"Adam"}};
const uint8_t nbIndividus =  sizeof individus / sizeof individus[0];
const uint8_t individuInconnu = 0xFF;

const uint8_t nbActions = nbTaches; // on pourrait en avoir plus
struct t_action {
  uint8_t indexTache;
  uint8_t indexIndividu;
  bool effectuee;
} actions[nbActions];

void affecterActions()
{
  uint8_t individu = 0;
  for (uint8_t i = 0; i < nbActions - 1; i++) {
    actions[i].indexIndividu = individu;
    actions[i].effectuee = false;
    individu = (individu + 1) % nbIndividus;
  }
}

void printActions(t_jour j = JourIgnore)
{
  if (j != JourIgnore) Serial.println(jours[j]);
  for (uint8_t i = 0; i < nbActions - 1; i++) {
    if ((j == JourIgnore) || (j == taches[actions[i].indexTache].jour)) {
      Serial.print(taches[actions[i].indexTache].nom);
      if (actions[i].indexIndividu != individuInconnu) {
        Serial.print(F(" (")); Serial.print(individus[actions[i].indexIndividu].nom); Serial.println(F(")"));
      } else Serial.println(F(" (non affectée)"));
      Serial.print(F("\tDurée: ")); Serial.println(taches[actions[i].indexTache].duree);
      Serial.print(F("\tDifficulté: ")); Serial.println(taches[actions[i].indexTache].difficulte);
      Serial.print(F("\tRécurente: ")); Serial.println(taches[actions[i].indexTache].recurente ? F("OUI") : F("NON"));
      Serial.print(F("\tJour: ")); Serial.println(jours[taches[actions[i].indexTache].jour]);
      Serial.println();
    }
  }
  Serial.println(F("----------------------"));
}

void trierActions() // bubbleSort, pas le plus efficace mais OK
{
  for (uint8_t i = 0; i < nbTaches - 1; i++)
    for (uint8_t j = 0; j < nbTaches - i - 1; j++) {
      uint8_t evalJ  = taches[actions[j].indexTache].duree + 5 * (taches[actions[j].indexTache].difficulte - 1);
      uint8_t evalJ1 = taches[actions[j + 1].indexTache].duree + 5 * (taches[actions[j + 1].indexTache].difficulte - 1);
      if (evalJ > evalJ1) {
        t_action tmp = actions[j];
        actions[j] = actions[j + 1];
        actions[j + 1] = tmp;
      }
    }
}

void setup() {
  Serial.begin(115200);

  // création des actions (ici on les prends toutes)
  for (uint8_t i = 0; i < nbActions; i++) {
    actions[i].indexTache = i % nbTaches;
    actions[i].indexIndividu = individuInconnu; // non affecté
  }
  trierActions();
  affecterActions();

  for (uint8_t jourActuel = 0; jourActuel < 7; jourActuel++) {
    printActions((t_jour) jourActuel);
  }
}

void loop() {}

avec cette approche, je sais que les variables globales utilisent 505 octets de mémoire dynamique. (un Uno n'a que 2k de RAM)

si vous exécutez le code, le moniteur série (à 115200 bauds) affichera

[color=purple]
Lundi
Vaisselle (William)
	Durée: 1
	Difficulté: 1
	Récurente: OUI
	Jour: Lundi

Douche (William)
	Durée: 5
	Difficulté: 2
	Récurente: OUI
	Jour: Lundi

----------------------
Mardi
Bar (William)
	Durée: 1
	Difficulté: 1
	Récurente: OUI
	Jour: Mardi

----------------------
Mercredi
----------------------
Jeudi
Lavabo (William)
	Durée: 2
	Difficulté: 1
	Récurente: OUI
	Jour: Jeudi

----------------------
Vendredi
Sortir poubelle (Adam)
	Durée: 5
	Difficulté: 3
	Récurente: OUI
	Jour: Vendredi

----------------------
Samedi
Table (Adam)
	Durée: 1
	Difficulté: 1
	Récurente: OUI
	Jour: Samedi

Tele (Adam)
	Durée: 1
	Difficulté: 1
	Récurente: OUI
	Jour: Samedi

Table basse (Adam)
	Durée: 4
	Difficulté: 1
	Récurente: OUI
	Jour: Samedi

Balais (William)
	Durée: 1
	Difficulté: 2
	Récurente: OUI
	Jour: Samedi

Serpillere (Adam)
	Durée: 1
	Difficulté: 2
	Récurente: OUI
	Jour: Samedi

Rentrer poubelle (William)
	Durée: 5
	Difficulté: 3
	Récurente: OUI
	Jour: Samedi

Toilette (Adam)
	Durée: 7
	Difficulté: 3
	Récurente: OUI
	Jour: Samedi

----------------------
Dimanche
----------------------

[/color]

Wow merci beaucoup, je ne connaissais pas le principe des structures et ça a en effet l'air beaucoup plus simple.

Je vais continuer de travailler dessus :slight_smile:

La Structure vient du C, et une classe c'est comme un structure en fait en C++ (à la quelle on peut attribuer des fonctions et l'héritage etc)

il faut surtout que vous évitiez tout ce qui peut être dynamique (donc la classe String par exemple)

williamlls:
En effet je me suis compliqué la vie pour la gestion des jours

Mais pas que.
C'est pareil pour tous les tableaux d'ints que tu utilises.

Par ailleurs, si la méthode CTask::Copie() ne fait que copier tous les membres bit à bit, tu peux la virer.
Le C++ t'offre gratuitement un constructeur par copie par défaut qui fait la même chose:

// le compilateur a fabriqué ce constructeur:
// CTask::CTask ( const CTask & );
// qui s'utilise comme ça:

CTask task1 ( ...arguments... );
task2 = CTask ( task1 ); // <--- task2 copie de task1

Dans sa générosité, le C++ t'offre aussi une fonction membre fort utile :

// la fonction est:
// CTask& CTask::operator= ( const CTask & );
// qui s'utilise comme ça:

CTask task1 ( ...arguments... );
task2 = task1; // <--- ENCORE PLUS SYMPA !!

D'accord :slight_smile:

Par contre pour les String, il faut les remplacer par des char* ? Ca reste de l'allocation dynamique non ?

Le C++ t'offre gratuitement un constructeur par copie par défaut qui fait la même chose:

pas si c'est du deep copy qui est nécessaire

williamlls:
Par contre pour les String, il faut les remplacer par des char* ? Ca reste de l'allocation dynamique non ?

Non ici tout est constant, donc des const char *. le compilateur les alloue à la compilation et sait combien de RAM est nécessaire.
Même si vous vouliez pouvoir éditer des choses, vous pourriez réserver une chaîne de caractère de taille fixe, par exemple char message[50]; --> le compilateur alloue les 50 octets et ça ne pourra jamais grandir (faut pas déborder)

(si la mémoire devient un souci, vous pourriez ensuite même les stocker en mémoire flash avec PROGMEM)

J-M-L:
Non ici tout est constant, donc des const char *.

Haaa d'accord j'ai bien compris merci :slight_smile:

biggil:
Mais pas que.
C'est pareil pour tous les tableaux d'ints que tu utilises.

Par ailleurs, si la méthode CTask::Copie() ne fait que copier tous les membres bit à bit, tu peux la virer.
Le C++ t'offre gratuitement un constructeur par copie par défaut qui fait la même chose:

J'avais remarqué en effet que la copie de Ctask vers CTask fonctionnait, mais je n'arrivais pas à trouver pourquoi... Dans le doute j'ai préféré surcharger étant donné que je travaillais sur Visual Studio.

Mais en effet, le C++ semble avoir tout prévu :slight_smile:

Je pense continuer en m'orientant vers les structures qui semblent très pratique :slight_smile:

Je reviens car j'ai déjà un problème en reprenant les structures.
Je rencontre ce problème lors de la déclaration de const char* jours[]
Le message d'erreur est le suivant :

TaskMeArduino5.0:10:19: error: two or more data types in declaration of 'jours'
TaskMeArduino5.0:19:3: error: expected '}' before '{' token
TaskMeArduino5.0:19:3: error: expected ',' or ';' before '{' token
TaskMeArduino5.0:19:33: error: expected unqualified-id before ',' token
TaskMeArduino5.0:20:3: error: expected unqualified-id before '{' token
TaskMeArduino5.0:20:30: error: expected unqualified-id before ',' token
TaskMeArduino5.0:21:3: error: expected unqualified-id before '{' token
TaskMeArduino5.0:21:34: error: expected unqualified-id before ',' token
TaskMeArduino5.0:22:3: error: expected unqualified-id before '{' token
TaskMeArduino5.0:22:38: error: expected unqualified-id before ',' token
TaskMeArduino5.0:23:3: error: expected unqualified-id before '{' token
TaskMeArduino5.0:23:36: error: expected unqualified-id before ',' token
TaskMeArduino5.0:24:3: error: expected unqualified-id before '{' token
TaskMeArduino5.0:24:33: error: expected unqualified-id before ',' token
TaskMeArduino5.0:25:3: error: expected unqualified-id before '{' token
TaskMeArduino5.0:25:33: error: expected unqualified-id before ',' token
TaskMeArduino5.0:26:3: error: expected unqualified-id before '{' token
TaskMeArduino5.0:26:39: error: expected unqualified-id before ',' token
TaskMeArduino5.0:27:3: error: expected unqualified-id before '{' token
TaskMeArduino5.0:27:32: error: expected unqualified-id before ',' token
TaskMeArduino5.0:28:3: error: expected unqualified-id before '{' token
TaskMeArduino5.0:28:35: error: expected unqualified-id before ',' token
TaskMeArduino5.0:29:3: error: expected unqualified-id before '{' token
TaskMeArduino5.0:29:42: error: expected unqualified-id before ',' token
TaskMeArduino5.0:30:3: error: expected unqualified-id before '{' token
TaskMeArduino5.0:31:1: error: expected declaration before '}' token
Utilisation de la bibliothèque LiquidCrystal version 1.0.7 dans le dossier: C:\Program Files (x86)\Arduino\libraries\LiquidCrystal 
Utilisation de la bibliothèque DS1302 prise dans le dossier : C:\Users\lalis\OneDrive\Documents\Arduino\libraries\DS1302 (legacy)
exit status 1
two or more data types in declaration of 'jours'

J'avoue que la déclaration de tableau de char n'est pas encore très bien acquise pour moi, je n'arrive donc pas à comprendre le problème...

Autre point : const uint8_t nbIndividus = sizeof individus / sizeof individus[0];

La taille de individus[0] est différente de individus[1] non ?
Ainsi le nombre nbIndividus risques de ne pas être correcte bien que ça soit un const uint dans le cas où je
souhaiterais ajouter des individus.

faut me montrer le code :slight_smile:

#include <LiquidCrystal.h>
#include <DS1302.h>

DS1302 rtc(8, 10, 11);
const int rs = 2, en = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


enum t_jour : uint8_t {Lundi, Mardi, Mercredi, Jeudi, Vendredi, Samedi, Dimanche, JourIgnore}
const char* jours[] = {"Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"};

struct t_task{
  const char* nom;
  const uint8_t duree;
  const uint8_t difficulte;
  t_jour jour;
} taches[]={
  {"Vaisselle",1,1,Lundi}
  {"Table", 1, 1, true, Samedi },
  {"Bar", 1, 1, true, Mardi },
  {"Balais", 1, 2, true, Samedi },
  {"Serpillere", 1, 2, true, Samedi },
  {"Toilette", 7, 3, true, Samedi },
  {"Douche", 5, 2, true, Lundi },
  {"Lavabo", 2, 1, true, Jeudi },
  {"Table basse", 4, 1, true, Samedi },
  {"Tele", 1, 1, true, Samedi },
  {"Tapis", 10, 3 , true, Samedi },
  {"Sortir poubelle", 5, 3, true, Mardi },
  {"Rentrer poubelle", 5, 3, true, Mercredi }
}
const uint8_t nbtaches= sizeof taches / sizeof taches[0];

struct t_individu{
  const char* nom;
} individus[]={{"William"},{"Adam"}};
const uint8_t nbIndividus = 2;




void setup() {
  // put your setup code here, to run once:
  pinMode(boutonScroll,INPUT_PULLUP);
  pinMode(boutonTask,INPUT_PULLUP);

  // ------ Time ------
  rtc.halt(false);
  rtc.writeProtect(false);
  rtc.setDOW(SATURDAY);        // Set Day-of-Week
  //rtc.setTime(20, 52, 10);     // Set the time to 12:00:00 (24hr format)
  //rtc.setDate(3, 18, 2021);   // Set the date to August 6th, 2010*/
  // ------------------

  Serial.begin(9600);
  for(uint8_t i=0;i<nbtaches;i++)
  {
    Serial.print("Nom : ");
  }
  lcd.begin(16, 2);
  analogWrite(8,15);
}

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

J'ai essayé de faire un test plus simple :

const int* test[] = {1,2,3];

J'ai la même erreur.

const int* test[];
const int* test;

Egalement l'erreur.

vous avez oublié le ; à la fin de la ligne avec l'enum

Merci :sweat_smile:
J'ai réussi aussi à le voir au bout de 30min ... Décidément :slight_smile:

Encore merci pour l'info sur les structures, j'adore ça :slight_smile:

const int* test[] = {1,2,3];

==> il faut une accolade fermante pour la fin de la définition des valeurs du tableau
=> le type est sans doute erroné, ici vous dites que le tableau test contient des pointeurs sur entiers...

donc plutôt ceci:const int test[] = {1,2,3};

En fait l'erreur venait aussi du ; manquant :sweat_smile:

Sinon j'essaie de remodeler l'exemple que vous m'avez donner pour bien le comprendre, et je constate que le tableau taches[] est statique. Je ne peux donc plus trier les tâches pour les attribuer si ?
Sachant que je trie en fonction de la difficulté et du temps .
J'ai essayé de les permuter comme dans un tableau dynamique mais ça ne fonctionne malheureusement pas.