Language learning aid

Hi all
I've been visiting this forum since forever, but I think I never posted. So, short introduction, I'm Sebastiaan from the Netherlands. Been fiddling with Arduino for years now, but nothing fancy.

Lately l noticed my son struggling with his homework, especially foreign languages (german, french)
I comitted to making a learning aid. Something like Duolingo.
I'd like to have 4 buttons on the left with dutch words, and 4 buttons on the right with different french words in random order. He has to 'find the pairs'.
So I found out I was in way over my head. So I turned to AI. It helped me lots but now I'm stuck.

I use an Uno with a tft touch shield.

My code gives me four working buttons (rest will come) with words in it. The first difficulty is making arduino recognise the 'pairs' and act accordingly. It will nog give me an output, either right or wrong.

The next step is for arduino to choose the words from a csv array and put the french words in a random order. (always four pairs however) Also I need to make sure it will not act on a specific button but on the value in that button, since order will change.
Next steps will folow, hopefully without leaning on others too much.

Code down below!
Hopefully I can get some help and see my sons grades improve a bit.

Oh, if needed I'll translate the dutch notes.


#include <woordenlijst.h>
#include <Adafruit_GFX.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;       // hard-wired for UNO shields anyway.
#include <TouchScreen.h>
#define MINPRESSURE 10
#define MAXPRESSURE 1000
const int XP=8,XM=A2,YP=A3,YM=9; //320x480 ID=0x9486
const int TS_LEFT=118,TS_RT=903,TS_TOP=934,TS_BOT=87;
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
Adafruit_GFX_Button 
NL1_btn, F1_btn, NL2_btn, F2_btn;
int pixel_x, pixel_y;     //Touch_getXY() updates global vars
bool Touch_getXY(void)
{
   TSPoint p = ts.getPoint();
   pinMode(YP, OUTPUT);      //restore shared pins
   pinMode(XM, OUTPUT);
   digitalWrite(YP, HIGH);   //because TFT control pins
   digitalWrite(XM, HIGH);
   bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
   if (pressed) {
       pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width()); //.kbv makes sense to me
       pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
   }
   return pressed;
}
// Assign human-readable names to some common 16-bit color values:
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
// Constanten voor het scherm
const int knopBreedte = 100;
const int knopHoogte = 30;
const int marge = 10;
struct WoordPaar {
String Nederlands;
String Frans;
};
WoordPaar woordparen[] = {
 {"vader", "pere"},
 {"moeder", "mere"},
};
//functie om te controleren of een woordpaar correct is
bool isCorrectPaar(String nlWoord, String frWoord) {
for (int i = 0; i < sizeof(woordparen) / sizeof(woordparen[0]); i++) {if (woordparen[i].Nederlands == nlWoord && woordparen[i].Frans == frWoord) { 
 return true;
}
}
return false;
}
void setup(void)
{
   {Serial.begin(9600);
   uint16_t ID = tft.readID();
   Serial.print("TFT ID = 0x");
   Serial.println(ID, HEX);
   Serial.println("Calibrate for your Touch Panel");
   if (ID == 0xD3D3) ID = 0x9486; // write-only shield
   tft.begin(ID);
   tft.setRotation(0);            //PORTRAIT
   tft.fillScreen(BLACK);
   NL1_btn.initButton(&tft,  80, 200, 145, 40, WHITE, CYAN, BLACK, "vader", 2); //80=hoogte 200=breedte 145=breedte knop 40=hoogte knop 2=lettergrootte
   F2_btn.initButton(&tft, 230, 200, 145, 40, WHITE, CYAN, BLACK, "mere", 2); //white=rand om knop cyan=knopkleur black=letterkleur
   NL2_btn.initButton(&tft,  80, 260, 145, 40, WHITE, CYAN, BLACK, "moeder", 2);
   F1_btn.initButton(&tft,  230, 260, 145, 40, WHITE, CYAN, BLACK, "pere", 2);
   
 NL1_btn.drawButton(false);
 NL2_btn.drawButton(false);
 F1_btn.drawButton(false);
F2_btn.drawButton(false);
}
  
}



void loop(){

bool down = Touch_getXY();
 // Controleer alle knoppen en voer de bijbehorende actie uit
 NL1_btn.press(down && NL1_btn.contains(pixel_x, pixel_y));
 if (NL1_btn.justPressed()) {
    NL1_btn.drawButton(true);
 }


 NL2_btn.press(down && NL2_btn.contains(pixel_x, pixel_y));
 if (NL2_btn.justPressed()) {
   NL2_btn.drawButton(true);
 }
   F1_btn.press(down && F1_btn.contains(pixel_x, pixel_y));
 if (F1_btn.justPressed()) {
   F1_btn.drawButton(true);
 }
     F2_btn.press(down && F2_btn.contains(pixel_x, pixel_y));
 if (F2_btn.justPressed()) {
   F2_btn.drawButton(true);
 }
   if (NL1_btn.contains(pixel_x, pixel_y) && F1_btn.contains(pixel_x, pixel_y)) {
   if (isCorrectPaar("vader", "pere"))
   {tft.fillScreen(GREEN);
   delay(500);
   tft.fillScreen(BLACK);}
   else{tft.fillScreen(RED);
   delay(500);
   tft.fillScreen(BLACK);}
   
 }
}

Feed it through your ai a couple more times to populate the buttons and use them for isCorrectPaar()

i see code to draw buttons and fill screens.

i don't see code with text words that need to be matched.

i've found the graphical interface to be much more work than the primary application. it's often easier to get each part to work independently and then combine them

Is duolingo not available for dutch?
Because the App Duolingo offers so many different types of exercises this would be much better.

Or shall your son not have a smartphone?

An Arduino Uno has only 2 kB of RAM which seems pretty low for a graphical display.

Thanks so far guys!

@roboPiggyback I've been trying that for some hours. My AI doesn't seem to understand what's wrong, and instead it will start to rebuild sections that work fine...

@gcjr lines 10-14 in setup gives me 4 buttons with text. Coding for it choosing text will follow but not before this works.
I tried to do it in parts and came so for yet.

@StefanL38 duolingo is fantastic. I finished an englisch course and am bow half way through french. However it has not the same words as my sons gramar books. He can practise for weeks without learning the words from the first chapter in his book. That's why I'd like to choose the words so they match his chapters...
Arduino is not that great for graphical indeed, but there's no need for sleek interfaces. Just a black screen and some buttons. Maybe a score counter in the future.
I hope arduino can manage....

If you have fun with programming it for Arduino fine.
Though there are a lot of vocabulary-apps for smartphones. This would reduce the work to
just enter the words.
Or shall your son not be "playing" with a smartphone so much?

Yeah, well... where's the fun in that 'ey!?

I'm a creative guy who likes building stuff. Also I like to challenge myself so I know more tomorrow than I do today.
Hope my kids will see and pick it up.

My son can use his smartphone whenever he wants (within boundaries) but I hope this project gives him extra stimulance to study.

To go back on topic, I've fed my code to chatgpt who did manage to find the fault, where Gemini failed. So I'm a step further. Learning to use SD card is the next step.
So for now I've found answers, hopefully some of you are willing to give me some pointers in the nearby future.

Have a good one y'all!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.