Inhaltsverzeichnis:

Gefälschtes dynamisches Preisschild - Gunook
Gefälschtes dynamisches Preisschild - Gunook

Video: Gefälschtes dynamisches Preisschild - Gunook

Video: Gefälschtes dynamisches Preisschild - Gunook
Video: Die DAG bald ohne Autos ? I 5000mille Nachlass?! Kundenstorys I 60Std. Woche im Autohandel normal ? 2024, November
Anonim
Image
Image
Verkabeln Sie das Display
Verkabeln Sie das Display

Die Preise von Amazon ändern sich ständig. Wenn Sie Artikel länger als ein paar Stunden in Ihrem Warenkorb lassen, werden Sie wahrscheinlich über winzige Schwankungen informiert – 0,10 USD hier, 2,04 USD dort. Amazon und seine Händler verwenden offensichtlich eine Form der algorithmischen Preisgestaltung, um den letzten Cent aus dem Markt zu quetschen.

Das ist alles zu erwarten (Spätkapitalismus und so). Aber was passiert, wenn etwas schief geht? Im Jahr 2011 brach ein Preiskrieg zwischen zwei konkurrierenden Algorithmen aus. Das Ergebnis: Ein Buch über den Lebenszyklus von Stubenfliegen (vergriffen, aber nicht besonders selten) schoss auf einen Preis von 23,6 Millionen US-Dollar in die Höhe.

Die jüngste Übernahme des Whole Foods Market durch Amazon ließ uns fragen: Was hindert Dynamic Pricing daran, in die physische Welt des Einzelhandels einzudringen? Was wäre, wenn die Preise im Supermarkt genauso flexibel wären wie im Internet?

Also, in diesem Instructable bauen wir eine dynamische Preisanzeige mit einem Arduino und einem kleinen LCD. Wir werden auch kurz über das Verkleiden und Installieren in einem Geschäft sprechen.

(Und wenn Sie interessiert sind, kann Ihnen dieses Chrome-Plugin den Preisverlauf jedes Artikels bei Amazon in den letzten 120 Tagen anzeigen.)

Benötigtes Material

Hier ist, was wir verwendet haben, um dieses Projekt zu erstellen:

  • Ein Arduino Uno R3
  • Ein standardmäßiges 16x2-LCD-Display. Wir haben dieses von Adafruit verwendet, aber solange es mit der LiquidCrystal-Bibliothek kompatibel ist, sollten Sie gut sein. Sie benötigen ein paar Dinge, um es mit dem Arduino zu verbinden:

    • einige Überbrückungskabel
    • ein 220 Ohm Widerstand
    • ein 10k Ohm Potentiometer (Dies dient zur Steuerung des Kontrasts des Displays. Wenn Sie einen Kontrast finden, der Ihnen gefällt, können Sie das Potentiometer durch einen Festwiderstand ersetzen.)
  • Etwas Acryl für die Box. Wir verwendeten ein gegossenes mattschwarzes Acryl, das lasergeschnitten und mit Acryl-Lösungsmittelkleber und Heißkleber zusammengebaut wurde.
  • Magnete und/oder ein Regalhaken zur Befestigung der Box im Geschäft. Wenn Sie den Hakenweg gehen, könnten Sie einen ausmessen und in 3D drucken oder versuchen, einen online zu finden (Alibaba vielleicht?) oder … ihn auf andere, schändlichere Weise erwerben. Sicher sein.

Lassen Sie uns zuerst die Anzeige in Gang bringen!

Schritt 1: Verdrahten Sie das Display

Verkabeln Sie das Display
Verkabeln Sie das Display
Verkabeln Sie das Display
Verkabeln Sie das Display

Es gibt sicher viele Pins auf der Rückseite dieses LCD. Glücklicherweise enthält die Dokumentation für die Softwarebibliothek, die wir verwenden werden, eine gute Anleitung zur Verkabelung. Hör zu.

Zusammenfassend sollte Ihre Verkabelung so aussehen:

  • Leistung:

    • LCD GND (Pin 1) → Arduino GND
    • LCD VDD (Pin 2) → Arduino +5V
    • LCD RW (Pin 5) → Arduino GND
  • Datenmaterial:

    • LCD RS (Pin 4) → Arduino digitaler Pin 12
    • LCD-Aktivierung (Pin 6) → Arduino digitaler Pin 11
    • LCD D4 (Pin 11) → digitaler Pin 5
    • LCD D5 (Pin 12) → Digital Pin 4
    • LCD D6 (Pin 13) → Digital Pin 3
    • LCD D7 (Pin 14) → Digital Pin 2
  • Displaykontrast:

    • Verdrahten Sie die Beine eines 10k-Potentiometers mit Arduinos +5V und GND
    • Ausgang des Potentiometers → LCD VO (Pin 3).
  • Hintergrundbeleuchtung:

    • LCD BL1 (Pin 15) → 220 Ohm Widerstand → Arduino +5V
    • LCD BL2 (Pin 16) → Arduino GND

Wenn das alles eingerichtet ist, laden Sie eines der LiquidCrystal-Beispielprojekte in der Arduino IDE und sehen Sie, ob es funktioniert! Denken Sie daran, den LCD-Initialisierungscode in den Beispielen zu überprüfen – die Pin-Nummern müssen korrekt sein, sonst sehen Sie nichts.

Das Beispiel "Blink" hat beispielsweise diesen Code, der bei der obigen Konfiguration korrekt ist:

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;Flüssigkristall lcd(rs, en, d4, d5, d6, d7);

Tipps

  • Sparen Sie sich das Löten und investieren Sie in einige Crimpenden und Header-Steckverbinder. Bei Projekten wie diesem, bei denen wir die Elektronik in ein kleines Gehäuse stopfen werden, ist es unglaublich hilfreich, kurze Überbrückungskabel herstellen zu können.
  • Ebenso ist ein Schrumpfschlauch wirklich nützlich, um sicherzustellen, dass nichts kurzgeschlossen wird, wenn alles gegen sich selbst gedrückt wird.
  • Da so viele Dinge an GND und +5V gehen, haben wir uns dafür entschieden, ein Frankenkabel (siehe Foto oben) so kompakt wie möglich zu machen. Wenn der Platz weniger ein Problem wäre, wäre ein Steckbrett oder ein Protoshield eine einfachere Option gewesen.
  • Einige Potentiometer sind seltsam geformt. Im Allgemeinen wird die linke Leitung als Masse, die ganz rechte Leitung als Strom und die mittlere als Ausgang verwendet. Wenn Ihres zwei Anschlüsse auf der Vorderseite und eine auf der Rückseite hat, ist die eine auf der Rückseite der Ausgang.

Fallstricke

  • Wenn Sie nichts auf Ihrem LCD sehen, versuchen Sie, das Potentiometer ganz in eine Richtung zu drehen und dann in die andere. Bei niedrigstem Kontrast ist der Inhalt des LCD komplett unsichtbar.
  • Wenn Sie wirklich seltsames Kauderwelsch auf dem LCD sehen oder nur eine Zeile anstelle von zwei, stellen Sie sicher, dass alle Ihre Verbindungen sicher sind. Wir hatten eine fehlerhafte Verbindung zur Masse und dies verursachte die seltsamsten Anzeigeprobleme.
  • Der LCD-Initialisierungscode (was von lcd.init() in der setup()-Funktion ausgeführt wird) ist wichtig und dauert eine Weile. Wenn etwas mit Ihrem Display nicht stimmt und Sie ein defektes Kabel vermuten, erwarten Sie nicht, dass es plötzlich funktioniert, wenn etwas wackelt. Möglicherweise müssen Sie das Arduino zurücksetzen, damit der Initialisierungscode ordnungsgemäß ausgeführt werden kann.
  • Stellen Sie sicher, dass Ihre Drähte ziemlich kurz sind, aber nicht zu kurz. Nichts ist schlimmer, als nachlöten zu müssen, weil Sie nur wenige Zentimeter von einem Header entfernt sind.

Groß! Lassen Sie uns jetzt einige ausgefallene Dinge zeigen.

Schritt 2: Code: Grundlagen

Code: Grundlagen
Code: Grundlagen
Code: Grundlagen
Code: Grundlagen

Das Wichtigste zuerst: Lassen Sie uns in der obersten Zeile "Aktueller Preis:" anzeigen und in der zweiten einen zufälligen Preis in einem bestimmten Bereich. Lassen Sie uns von Zeit zu Zeit den Preis aktualisieren. Dies ist ziemlich einfach, wird aber die grundlegende Verwendung der LiquidCrystal-Bibliothek und einige ihrer Eigenheiten hervorheben.

Lassen Sie uns zuerst die Bibliothek aufrufen und einige Konstanten definieren:

#enthalten

const uint8_t lcdWidth = 16;

const uint8_t lcdHeight = 2;

const long minPriceInCents = 50;

const long maxPriceInCents = 1999;

const unsigned long minMillisBetweenPriceUpdates = 0,25 * 1000;

const unsigned long maxMillisBetweenPriceUpdates = 2 * 1000

Groß! Dies sind die Parameter für die Preisspanne und wie oft sie aktualisiert wird. Lassen Sie uns nun eine Instanz der von der Bibliothek bereitgestellten LCD-Klasse erstellen und sie initialisieren. Wir werden etwas über die serielle Konsole ausdrucken, um uns zu vergewissern, dass die Dinge funktionieren, auch wenn wir nichts auf dem LCD sehen. Das machen wir in der setup()-Funktion, die einmal nach dem Arduino-Boot ausgeführt wird. Beachten Sie jedoch, dass wir die lcd-Variable außerhalb von setup() deklarieren, da wir im gesamten Programm darauf zugreifen möchten.

Flüssigkristall-LCD (12, 11, 5, 4, 3, 2); Void setup () { Serial.begin (9600); lcd.begin(lcdWidth, lcdHeight);

Serial.println ("LCD initialisiert");

lcd.print("Aktueller Preis:");

}

Und für das Fleisch verwenden wir die eingebaute Funktion random() und den Initialisierer String(), um einen dezimalen Preis zu konstruieren. random() generiert nur Ganzzahlen, daher teilen wir das Ergebnis durch 100,0, um einen Gleitkommawert zu erhalten. Wir werden dies in loop() tun, also geschieht dies so oft wie möglich, aber mit einer zufälligen Verzögerung zwischen den zuvor definierten Konstanten.

Leere Schleife ()

{ doppelter Preis = zufällig (minPriceInCents, maxPriceInCents) / 100,0; String hübscher Preis = "$" + String(Preis, 2); lcd.setCursor(0, 1); lcd.print (prettyPrice); Verzögerung (zufällig (minMillisBetweenPriceUpdates, maxMillisBetweenPriceUpdates)); }

Zu beachten ist der Aufruf von lcd.setCursor(). Die LiquidCrystal-Bibliothek rückt Ihren Text nach einem Druck nicht automatisch in die nächste Zeile vor, daher müssen wir den (unsichtbaren) Cursor manuell in die zweite Zeile bewegen (hier 1 – nullbasiert). Beachten Sie auch, dass wir "Aktueller Preis:" nicht erneut drucken mussten; das LCD wird nicht gelöscht, es sei denn, Sie tun dies manuell, sodass wir nur den dynamischen Text aktualisieren müssen.

Probieren Sie es aus und Sie werden schnell ein damit verbundenes Problem sehen. Wenn der Preis beispielsweise „14,99 $“und dann „7,22 $“war, zeigt das Display „7,229 $“an. Denken Sie daran, dass sich das Display nicht selbst löscht, es sei denn, Sie sagen es. Selbst wenn Sie in derselben Zeile drucken, bleibt der Text, der über das hinausgeht, was Sie drucken. Um dieses Problem zu beheben, müssen wir unseren String mit Leerzeichen auffüllen, um jeglichen potenziellen Müll zu überschreiben. Der einfachste Weg, dies zu tun, besteht darin, einfach ein paar Leerzeichen an unsere PrettyPrice-Variable anzuhängen:

String hübscher Preis = "$" + String(Preis, 2) + " ";

Mit dieser Änderung haben wir einen Proof of Concept! Lass es uns ein bisschen aufpeppen.

Schritt 3: Code: Benutzerdefinierte Zeichen

Code: Benutzerdefinierte Zeichen
Code: Benutzerdefinierte Zeichen
Code: Benutzerdefinierte Zeichen
Code: Benutzerdefinierte Zeichen

Eine der coolsten Funktionen des von uns verwendeten LCD-Moduls ist die Möglichkeit, bis zu 8 benutzerdefinierte Zeichen zu erstellen. Dies geschieht über die Methode createChar(). Diese Methode benötigt ein Array von 8x5 Bits, die beschreiben, welche Pixel des LCDs für das gegebene Zeichen eingeschaltet werden sollen. Es gibt einige Online-Tools, die beim Generieren dieser Arrays helfen. Ich habe diesen benutzt.

Wenn Sie sich nicht besonders designorientiert fühlen, empfehle ich, den Schwellenwertfilter in Photoshop zu verwenden, um ein Bild in Schwarzweiß umzuwandeln und dieses in Zeichen umzuwandeln. Denken Sie daran, dass Sie maximal 8 benutzerdefinierte Zeichen oder 64 x 5 Pixel haben.

Ich habe mich dafür entschieden, 6 dieser Zeichen für das Amazon-Pfeillogo und die restlichen 2 für ein schöneres Markensymbol zu verwenden. Sie können dem CustomCharacter-Beispiel in der Arduino IDE folgen, um die API zu verwenden. So habe ich beschlossen, die Dinge zu gruppieren:

// Definieren Sie die Daten für die Markenzeichen

const size_ttrademarkCharCount = 2;const uint8_ttrademarkChars[trademarkCharCount][8] = { { B00111, B00010, B00010, B00000, B00000, B00000, B00000, B00000 }, { B10100, B11100, B10100, B00000, B00000, B00000, B00000, B00000 } }; uint8_t firstTrademarkCharByte; // Das Byte, das verwendet wird, um dieses Zeichen zu drucken; in initCustomChars() zugewiesen

Dann habe ich eine Funktion wie diese verwendet, die von setup() aufgerufen wird, um die Zeichen zu erstellen:

void initCustomChars() {

firstTrademarkCharByte = 0; for(size_t i = 0; i <trademarkCharCount; i++) { lcd.createChar(logoCharCount + i, (uint8_t *)trademarkChars); } }

Danach ist das Drucken der benutzerdefinierten Zeichen so einfach wie die Verwendung von lcd.write() mit den entsprechenden Bytes. Ich habe eine Hilfsfunktion geschrieben, um einen Bereich von Bytes zu drucken, und printTrademark () in Bezug darauf definiert:

void writeRawByteRange(uint8_t line, uint8_t col, uint8_t startValue, size_t numBytes)

{ for(uint8_t i = 0; i < numBytes; i++) { lcd.setCursor (col + i, line); // muss write() verwenden, nicht print() - print wandelt den ganzzahligen // Wert in einen String um und druckt *das* lcd.write(startValue + i); aufrechtzuerhalten. aufrechtzuerhalten. }

Das Amazon-Pfeillogo wurde ähnlich behandelt. Ausführliche Informationen finden Sie im beigefügten Code.

Schritt 4: Code: Nettigkeiten

Um es mir ein wenig einfacher zu machen, habe ich dem Code ein paar Feinheiten hinzugefügt. Dazu gehören Dinge wie: eine Funktion zum Löschen einer bestimmten Zeile durch Überschreiben mit Leerzeichen und eine Funktion zum Zentrieren einer bestimmten Zeichenfolge in einer Zeile.

Ich wollte auch, dass die Anzeige drei verschiedene Phasen durchläuft:

  1. "Dynamic Pricing" mit dem Logo unten
  2. "von Amazon" mit dem Logo unten
  3. zufällige Preisanzeige

Dafür habe ich ein einfaches System entwickelt, das verfolgt, wie lange eine bestimmte Phase aktiv war, und nach einer bestimmten Zeit zur nächsten übergeht.

Alle blutigen Details finden Sie im beigefügten Code!

Schritt 5: Die Box

Die Kiste
Die Kiste

Damit das Bombenkommando nicht zu uns gerufen wird, machen wir eine schöne Kiste für das Ganze. Wir machen das mit lasergeschnittenem Acryl. Es gibt viele Online-Tools, um den Prozess der Herstellung einfacher Boxen zu beschleunigen. Ich empfehle makercase.com, da Sie hier die Innenmaße angeben und die Dicke des Materials berücksichtigen können.

Wir haben die Arduino-, LCD- und 9-V-Batterie gemessen und geschätzt, dass wir sie in ein Gehäuse mit den Maßen 4 "x 2,5" x 2" einbauen können. Also steckten wir diese in ein Makercase mit einer Dicke von 1/8" Acryl. Wir haben das resultierende PDF modifiziert, um ein abgerundetes Fenster für das LCD und einen Schlitz am unteren Rand für ein Display-Tag hinzuzufügen (dazu später mehr). Die resultierende Datei wird als PDF angehängt.

Wir haben Acrylkleber (die giftige Methylethylketon-Art) verwendet, um vier Seiten der Schachtel zu montieren. Dann haben wir das LCD-Panel mit Heißkleber an der Vorderseite befestigt. Nachdem alles funktioniert und gepasst hatte, versiegelten wir die letzten beiden Seiten der Box mit Heißkleber, damit wir sie später leicht auseinandernehmen konnten. Da wir nicht erwarteten, dass das Gerät viel Verschleiß erfährt, haben wir das Arduino und den Akku ungesichert auf der Unterseite des Gehäuses gelassen.

Potenzielle Verbesserungen

  • Wir haben es versäumt, das Gerät in irgendeiner Weise ein- oder auszuschalten. Ha. Platz für einen Schalter auf der Unterseite oder Rückseite der Box wäre eine gute Idee gewesen.
  • Der Schlitz am Boden für das hängende Etikett hätte näher an der Vorderseite der Box sein können, um die Sichtbarkeit zu verbessern.

Schritt 6: Einmischen

Einblenden
Einblenden
Einblenden
Einblenden

Und jetzt der schwierige Teil: es in einen Laden zu schmuggeln.

Whole Foods-Branding

Einige Dinge, die wir beim Reverse-Engineering von Whole Foods und dem Amazon-Branding gelernt haben:

  • Der Fließtext ist im Allgemeinen in Scala Sans
  • Der Kopfzeilentext ist in etwas, das Brighton sehr ähnlich sieht – einer dieser generischen "warmen und freundlichen" Schriftarten
  • Whole Foods Green ist etwas in der Nähe von #223323
  • Suchen Sie in Ihrem lokalen Geschäft nach Beispielen für grafische Elemente, die sich wiederholen: Sie mögen überbackene Ränder, Sunbursts und einfache Vektorgrafiken.

Das hängende Etikett

Wir schneiden einen Schlitz in den Boden des Acrylgehäuses, damit wir ein hängendes Etikett an der Box anbringen können, das erklärt, was los ist. Ein Beispiel finden Sie im angehängten PDF. Dieser ist so konzipiert, dass er ausgeschnitten und in den Schlitz eingesetzt wird; Es sollte ohne Klebstoff passen und halten.

Regale

Um die Box tatsächlich an einem Regal anzubringen, verwendet Whole Foods ziemlich Standard-Regalkomponenten. Wir haben gemessen und in einem Baumarkt einen passenden Haken gefunden. Wir haben die Box mit Heißkleber am Haken befestigt.

Wenn Sie keinen solchen Haken finden, können Sie es mit Magneten versuchen – kleben Sie einige auf die Rückseite der Schachtel und rasten Sie sie einfach in ein Regal ein.

Einsetzen

Stellen Sie die Box auf Augenhöhe auf, um die Aufmerksamkeit der Passanten auf sich zu ziehen. Lass dich nicht erwischen! Viel Glück!