Arduino Uno Waage mit HX711 Programm



  • Hallo! Ich mach meine Facharbeit in Nwt, 10. Klasse Gymnasium. Ich baue einen Münzensortierer und brauch Hilfe ein Programm zu schreiben für ein Arduino Uno und HX711 und eine Feinwaage (0-100g). Das Programm müsste die Bereiche 7,5g-8,5g; 3,9g-5,7g; und 2,3g-4,7g abwiegen. Wär sehr lieb, danke!!



  • Hat jede Geldmünze eigentlich ein unterschiedliches Gewicht? Oder kann zum Beispiel ein 50-ct-Stück auch genau so viel wiegen wie ein 1-e-Stück? Ich will dir nicht die Idee klauen, aber hört sich super an. 🙂



  • Klar, zeig mal was du hast und welche konkreten Probleme du hast, dann helfen wir dir gerne. Wenn du dagegen meinst, dass dir jemand das komplette Programm hier schreibt, dann musst du dafür schon bezahlen 😉

    Siehe dazu bitte auch: https://www.c-plusplus.net/forum/topic/200753/bitte-lesen-du-brauchst-hilfe



  • Mir ist gerade etwas eingefallen, sehr interessant!

    Vorweg: Ich mache keine Hausaufgaben ...

    Ich hab mir mal die Gewichte der einzelnen Euromünzen herausgesucht: https://www.mdm.de/muenzwelt/euro-muenzen-uebersicht/gewicht-euromuenzen

    Fragestellung: Sei die Anzahl der Münzen bekannt ... Wie viele Euromünzen kann man auf eine Waage legen, und noch eindeutig bestimmen, welche Stücke auf der Waage liegen (ohne diese zu sehen, natürlich, nur durch das Wiegen)?

    Antwort: Nur 2!

    Herleitung (das mag jetzt nicht die beste Implementierung sein, aber sie sollte Sinn ergeben):

    #include <algorithm>
    #include <numeric>
    #include <deque>
    #include <vector>
    #include <iostream>
    using namespace std;
    
    // Zum Testen:
    // vector<int> gramm{
    //     5,
    //     6,
    //     8,
    //     9};
    
    vector<int> gramm{
        230,
        306,
        392,
        410,
        574,
        780,
        750,
        850};
    
    void calculate(const int n)
    {
        for (int n1 = 1; n1 <= n; n1++)
        {
            vector<int> v1(n1, 0);
            vector<int> v2(n1, 0);
    
            for (int i2 = n1 - 1; i2 >= 0;)
            {
                for (int i2 = n1 - 1; i2 >= 0;)
                {
                    vector<int> v3 = v1;
                    vector<int> v4 = v2;
                    sort(v3.begin(), v3.begin() + v3.size());
                    sort(v4.begin(), v4.begin() + v4.size());
                    if (v3 != v4)
                    {
                        int sum1 = 0;
                        int sum2 = 0;
                        for (int v : v3)
                        {
                            sum1 += gramm[v];
                        }
                        for (int v : v4)
                        {
                            sum2 += gramm[v];
                        }
                        if (sum1 == sum2)
                        {
                            cout << "FOUND: " << sum1 << endl;
                            cout << "FOUND: " << sum2 << endl;
                            for (auto v : v3)
                            {
                                cout << gramm[v] << " ";
                            }
                            cout << endl;
                            for (auto v : v4)
                            {
                                cout << gramm[v] << " ";
                            }
                            cout << endl;
                            cout << endl;
                        }
                    }
                    v2[i2]++;
                    if (v2[i2] == gramm.size())
                    {
                        while (i2 >= 0 && v2[i2] == gramm.size())
                        {
                            v2[i2] = 0;
                            i2--;
                            if (i2 >= 0)
                            {
                                v2[i2]++;
                            }
                        }
                        if (i2 >= 0)
                        {
                            i2 = n1 - 1;
                        }
                    }
                }
                v1[i2]++;
                if (v1[i2] == gramm.size())
                {
                    while (i2 >= 0 && v1[i2] == gramm.size())
                    {
                        v1[i2] = 0;
                        i2--;
                        if (i2 >= 0)
                        {
                            v1[i2]++;
                        }
                    }
                    if (i2 >= 0)
                    {
                        i2 = n1 - 1;
                    }
                }
            }
        }
    }
    
    int main(int argc, char const *argv[])
    {
        for (int i = 1; i <= 3; i++)
        {
            cout << i << endl;
            calculate(i);
        }
        return 0;
    }
    
    

    ... Und dann natürlich die Frage, wieso hat man die Münzen nicht besser entworfen? Hätte man eine 22,2, eine 33,3 und eine 99,1 g Münze genommen, hätte man sehr viel mehr Münzen auf die Waage packen können, und nur anhand des Gewichts sagen können, wie hoch der Gesamtbetrag ist...



  • Oje, da ist ein Fehler drin. Das sollte eigentlich i1 und i2 sein, nicht zweimal i1 ... das ist jetzt aber vermutlich der Uhrzeit geschuldet. 😞



  • So, nun aber ...

    #include <algorithm>
    #include <numeric>
    #include <deque>
    #include <unordered_set>
    #include <vector>
    #include <iostream>
    using namespace std;
    
    // Zum Testen:
    // vector<int> gramm{
    //     5,
    //     6,
    //     8,
    //     9};
    
    vector<int> gramm{
        230,
        306,
        392,
        410,
        574,
        780,
        750,
        850};
    
    struct VectorHash
    {
        size_t operator()(const std::vector<int> &v) const
        {
            hash<int> hasher;
            size_t seed = 0;
            for (int i : v)
            {
                seed ^= hasher(i) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
            }
            return seed;
        }
    };
    
    void calculate(const int n)
    {
        for (int n1 = 1; n1 <= n; n1++)
        {
            vector<int> v1(n1, 0);
            vector<int> v2(n1, 0);
            unordered_set<vector<int>, VectorHash> us1;
            for (int i1 = n1 - 1; i1 >= 0;)
            {
                for (int i2 = n1 - 1; i2 >= 0;)
                {
                    vector<int> v3 = v1;
                    vector<int> v4 = v2;
                    sort(v3.begin(), v3.end());
                    sort(v4.begin(), v4.end());
                    if (v3 != v4)
                    {
                        int sum1 = 0;
                        int sum2 = 0;
                        for (int v : v3)
                        {
                            sum1 += gramm[v];
                        }
                        for (int v : v4)
                        {
                            sum2 += gramm[v];
                        }
                        if (sum1 == sum2 && !us1.count(v3) && !us1.count(v4))
                        {
                            us1.insert(v3);
                            us1.insert(v4);
                            cout << "FOUND: " << sum1 << endl;
                            cout << "FOUND: " << sum2 << endl;
                            for (int v : v3)
                            {
                                cout << gramm[v] << " ";
                            }
                            cout << endl;
                            for (int v : v4)
                            {
                                cout << gramm[v] << " ";
                            }
                            cout << endl;
                            cout << endl;
                        }
                    }
                    v2[i2]++;
                    if (v2[i2] == gramm.size())
                    {
                        while (i2 >= 0 && v2[i2] == gramm.size())
                        {
                            v2[i2] = 0;
                            i2--;
                            if (i2 >= 0)
                            {
                                v2[i2]++;
                            }
                        }
                        if (i2 >= 0)
                        {
                            i2 = n1 - 1;
                        }
                    }
                }
                v1[i1]++;
                if (v1[i1] == gramm.size())
                {
                    while (i1 >= 0 && v1[i1] == gramm.size())
                    {
                        v1[i1] = 0;
                        i1--;
                        if (i1 >= 0)
                        {
                            v1[i1]++;
                        }
                    }
                    if (i1 >= 0)
                    {
                        i1 = n1 - 1;
                    }
                }
            }
        }
    }
    
    int main(int argc, char const *argv[])
    {
        for (int i = 1; i <= 4; i++)
        {
            cout << i << endl;
            calculate(i);
        }
        return 0;
    }
    

    Das gibt aus:

    1
    2
    3
    FOUND: 1730
    FOUND: 1730
    230 750 750 
    306 574 850 
    
    

    Das heißt, wenn ich 3 Münzstücke auf die Waage lege, und das Gewicht 17,3 Gramm beträgt, dann kann ich nicht mehr mit Sicherheit sagen, ob da 2,3 g + 7,5 g + 7,5 g ODER 3,06 g + 5,74 g + 8,5 g liegen, also ob der Betrag 1,02 € oder 2,22 € ist!



  • Hm, wenn man die 1ct, 1e und 2e herausnehmen würde, also man nur so etwas hätte:

    vector<int> gramm{
        306,  // 2 Cent
        392,  // 5 Cent
        410,  // 10 Cent
        574,  // 20 Cent
        780}; // 50 Cent
    

    Dann könnte man tatsächlich eindeutig bis zu 4 Münzen auf die Waage legen ... Die Ausgabe wäre dann:

    1
    2
    3
    4
    5
    FOUND: 2420
    FOUND: 2420
    306 392 574 574 574
    410 410 410 410 780
    
    

    So ... @rubdew sorry, dass ich dein Thema "gekapert" habe. Hast du schon eine Idee, wie du die Arduino Uno Waage ansprechen kannst? Das soll ja der Inhalt deiner "Facharbeit" sein. Wie gesagt, eine fertige Lösung können wir dir nicht liefern.



  • Moin, ich hab jetzt noch einmal etwas optimiert und einen "Fehler" entfernt ...

    Es geht auch dann, wenn die Anzahl der Münzen vorher unbekannt ist ...

    Probiert das gerne mal aus, ich hoffe, dass ich nun nix mehr übersehen habe:

    #include <algorithm>
    #include <numeric>
    #include <deque>
    #include <unordered_set>
    #include <vector>
    #include <iostream>
    using namespace std;
    
    /*
    // Zum Testen:
    vector<int> gramm{
        1,
        3};
    */
    
    vector<int> gramm{
        306,  // 2 Cent
        392,  // 5 Cent
        410,  // 10 Cent
        574,  // 20 Cent
        780}; // 50 Cent
    
    struct VectorHash
    {
        size_t operator()(const vector<int> &v) const
        {
            hash<int> hasher;
            size_t seed = 0;
            for (int i : v)
            {
                seed ^= hasher(i) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
            }
            return seed;
        }
    };
    
    void incrementVecp(vector<int> &vecp, int *ip, const int n)
    {
        vecp[*ip]++;
        if (vecp[*ip] == gramm.size())
        {
            while (*ip >= 0 && vecp[*ip] == gramm.size())
            {
                vecp[*ip] = 0;
                (*ip)--;
                if (*ip >= 0)
                {
                    vecp[*ip]++;
                }
            }
            if (*ip >= 0)
            {
                *ip = n - 1;
            }
        }
    }
    
    void calculate(const int n)
    {
        unordered_set<vector<int>, VectorHash> us1;
        for (int n1 = 1; n1 <= n; n1++)
        {
            for (int n2 = n1; n2 <= n; n2++)
            {
                vector<int> v1(n1, 0);
                vector<int> v2(n2, 0);
                for (int i1 = n1 - 1; i1 >= 0;)
                {
                    for (int i2 = n2 - 1; i2 >= 0;)
                    {
                        vector<int> v3 = v1;
                        vector<int> v4 = v2;
                        sort(v3.begin(), v3.end());
                        sort(v4.begin(), v4.end());
                        if (v3 != v4)
                        {
                            int sum1 = 0;
                            int sum2 = 0;
                            for (int v : v3)
                            {
                                sum1 += gramm[v];
                            }
                            for (int v : v4)
                            {
                                sum2 += gramm[v];
                            }
                            if (sum1 == sum2 && !us1.count(v3) && !us1.count(v4))
                            {
                                us1.insert(v3);
                                us1.insert(v4);
                                cout << "FOUND: " << sum1 << endl;
                                cout << "FOUND: " << sum2 << endl;
                                for (int v : v3)
                                {
                                    cout << gramm[v] << " ";
                                }
                                cout << endl;
                                for (int v : v4)
                                {
                                    cout << gramm[v] << " ";
                                }
                                cout << endl;
                                cout << endl;
                            }
                        }
                        incrementVecp(v2, &i2, n2);
                    }
                    incrementVecp(v1, &i1, n1);
                }
            }
        }
    }
    
    int main(int argc, char const *argv[])
    {
        for (int i = 1; i <= 5; i++)
        {
            cout << i << endl;
            calculate(i);
        }
        return 0;
    }
    
    ~/Documents/Muenzen$ ./a.out 
    1
    2
    3
    4
    5
    FOUND: 1970
    FOUND: 1970
    410 780 780 
    306 306 392 392 574 
    
    FOUND: 1928
    FOUND: 1928
    574 574 780 
    306 392 410 410 410 
    
    FOUND: 2420
    FOUND: 2420
    306 392 574 574 574
    410 410 410 410 780
    

    Solche kombinatorischen Probleme (numerische Mathematik?) sind zwar nicht neu, aber sie machen Spaß, und endlich auch mal etwas, wofür man C++ gut gebrauchen kann. 😉



  • Ich hab noch eine Idee/Fragestellung.

    Unter der Annahme, dass nur gleiche Münzen (also, alle Münzen haben denselben Geldwert) auf die Waage gelegt werden, aber man nicht weiß, um welche Münzen es sich handelt und wie viele aufgelegt wurden. Wie viele Münzen dürfen dann maximal auf die Waage gelegt werden, um noch rechnerisch ermitteln zu können, A welche Münzart (also der jeweilige Geldwert) aufgelegt wurde und B wie hoch der gesamte Münzbetrag (also der gesamte Geldwert) ist? Sprich, bis zu welcher Anzahl an Münzen sind alle Münzstapeltupel immer zwingend teilerfremd?

    @rubdew Aber diese Frage hat wahrscheinlich nix mit deiner Facharbeit zu tun ... Oder? Wie weit bist du denn jetzt? Wenn du schon etwas Vorzeigbares hast, können wir dich ggf. bei Fragen unterstützen.

    Langsam hab ich aber den Eindruck, diese Frage war gar nicht ernstgemeint gewesen ...


Anmelden zum Antworten