2012-12-29 23 views
5

से बाइनरी कमांड भेजना मुझे Arduino (Uno rev 3) और थर्मल प्रिंटर (यह मॉडल) के साथ खेलने में कुछ मज़ा आता है। Arduino मेरी स्थानीय मशीन (एक ईथरनेट शील्ड के माध्यम से) में हर 10 सेकंड का अनुरोध करता है और एसडी कार्ड पर प्रतिक्रिया (यदि 200) स्टोर करता है। इसके बाद यह इस पुस्तकालय https://github.com/adafruit/Adafruit-Thermal-Printer-Library का उपयोग करके इसे प्रिंट करता है।PHP से Arduino संचालित थर्मल प्रिंटर

अब तक मैंने इसे मूल पाठ को सही तरीके से मतदान, भंडारण और प्रिंटिंग किया है, लेकिन अब मैं कुछ अधिक उन्नत आदेशों (अंडरलाइन, उलटा इत्यादि) का उपयोग करने की कोशिश कर रहा हूं। मेरा अंतिम लक्ष्य छवियों को नीचे भेजना और सर्वर ala http://printer.gofreerange.com/ पर सभी प्रतिपादन को संभालना है।

समस्या यह है कि मैं जो आदेश भेज रहा हूं उसे पाठ वर्णों के रूप में आउटपुट किया गया है। कुछ आदेश काम करते हैं (लाइन फीड), लेकिन दूसरों को खराब कर दिया जाता है। मैंने Arduino कोड और मूल PHP स्क्रिप्ट दोनों को कॉल किया है जो इसे कॉल कर रहा है। कोई मदद?

Arduino:

#include <SPI.h> 
#include <Ethernet.h> 
#include <SD.h> 
#include <SoftwareSerial.h> 
#include "Adafruit_Thermal.h" 

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 
const char host[] = "192.168.1.100"; 
char cacheFilename[] = "TMP"; 

const byte printer_RX_Pin = 8; // this is the green wire 
const byte printer_TX_Pin = 9; // this is the yellow wire 
const byte SD_Pin = 4;   // the SD Card SPI pin 

bool downloadWaiting = false; 
bool statusOk = false; 
unsigned long content_length = 0; 

EthernetClient client; 
Adafruit_Thermal printer(printer_RX_Pin, printer_TX_Pin); 


void die(unsigned int times) { 
    while(true); 
} 


void checkForDownload() { 

    Serial.println("checkForDownload"); 

    content_length = 0; 
    statusOk = false; 
    unsigned long length = 0; 

    if (SD.exists(cacheFilename)) { 
    if (!SD.remove(cacheFilename)) { 
     die(4); 
    } 
    } 
    File cache = SD.open(cacheFilename, FILE_WRITE); 

    if(client.connect(host, 80)) { 

    client.println("GET /printer.php HTTP/1.1"); 
    client.print("Host: "); client.println(host); 
    client.println("User-Agent: arduino-ethernet"); 
    client.println("Connection: close"); 
    client.println(); 

    bool parsingHeader = true; 

    while(client.connected()) { 
     while(client.available()) { 

     if (parsingHeader) { 

      client.find((char*)"HTTP/1.1 "); 
      char statusCode[] = "000"; 
      client.readBytes(statusCode, 3); 
      statusOk = (strcmp(statusCode, "200") == 0); 

      client.find((char*)"Content-Length: "); 
      char c; 
      while (isdigit(c = client.read())) { 
      content_length = (content_length * 10) + (c - '0'); 
      } 

      client.find((char*)"\n\r\n"); 
      parsingHeader = false; 

     } else { 
      if(length < content_length) { 
      cache.write((byte)client.read()); 
      length++; 
      } else { 
       client.read(); 
      } 
     } 

     } 
    } 

    client.stop(); 
    cache.seek(0); 

    if (statusOk && content_length > 0 && (content_length == length) && (content_length == cache.size())) { 
     downloadWaiting = true; 
    } 

    } else { 
    client.stop(); 
    } 

    cache.close(); 

} 


void printFromDownload() { 

    Serial.println("printFromDownload"); 

    File cache = SD.open(cacheFilename); 
    byte b; 

    while (content_length--) { 
    printer.write((byte)cache.read()); 
    } 

    printer.feed(); 

    cache.close(); 
    downloadWaiting = false; 

} 


void setup(){ 

    pinMode(SD_Pin, OUTPUT); 
    if (!SD.begin(SD_Pin)) { 
    die(2); 
    } 

    if (Ethernet.begin(mac) == 0) { 
    die(3); 
    } 

    Serial.begin(9600); 
    printer.begin(255); 

    delay(1000); 

} 


void loop() { 
    if (downloadWaiting) { 
    printFromDownload(); 
    delay(5000); 
    } else { 
    checkForDownload(); 
    if (!downloadWaiting) { 
     delay(10000); 
    } 
    } 
} 

पीएचपी:

<?php 

ob_start(); 


// Turn on Inverse mode 
// Doesn't work 
echo pack('S', 29); 
echo pack('S', 66); 
echo pack('S', 1); 

$string = 'Testing 1, 2, 3'; 

foreach(str_split($string) as $char) { 
    echo pack('S', ord($char)); // works 
} 

// Turn off Inverse mode 
echo pack('S', 29); 
echo pack('S', 66); 
echo pack('S', 0); 

// Line feed 
echo pack('S', 10); // works 

$content = ob_get_clean(); 
$length = strlen($content); 
header("Content-Length: $length"); 

echo $content; 
+0

प्रिंटर दूषित होने वाले PHP को कौन सा डेटा भेज रहा है? – chugadie

उत्तर

0

ऐसा लगता है कि आप printer.write के साथ सीधे बिटमैप डेटा मुद्रित नहीं कर सकते()। प्रिंटर कुछ विशेष बाइट्स को बिटमैप प्रिंटिंग मोड चालू करने की अपेक्षा करता है जैसा कि आप printBitmap() विधि में देख सकते हैं। (WriteBytes (18, 42, chunkHeight, rowBytesClipped))

void Adafruit_Thermal::printBitmap(
int w, int h, const uint8_t *bitmap, bool fromProgMem) { 
    int rowBytes, rowBytesClipped, rowStart, chunkHeight, x, y, i; 

    rowBytes  = (w + 7)/8; // Round up to next byte boundary 
    rowBytesClipped = (rowBytes >= 48) ? 48 : rowBytes; // 384 pixels max width 

    for(i=rowStart=0; rowStart < h; rowStart += 255) { 
    // Issue up to 255 rows at a time: 
    chunkHeight = h - rowStart; 
    if(chunkHeight > 255) chunkHeight = 255; 

    writeBytes(18, 42, chunkHeight, rowBytesClipped); 

    for(y=0; y < chunkHeight; y++) { 
     for(x=0; x < rowBytesClipped; x++, i++) { 
     PRINTER_PRINT(fromProgMem ? pgm_read_byte(bitmap + i) : *(bitmap+i)); 
     } 
     i += rowBytes - rowBytesClipped; 
    } 
    timeoutSet(chunkHeight * dotPrintTime); 
    } 
    prevByte = '\n'; 
} 

आपका स्केच डेटा पीएचपी से आने वाले समझते हैं और जब printer.write साथ बाइट के रूप में अलग-अलग पात्रों भेजने के लिए() जब भेजने के लिए जानते हैं और करने की आवश्यकता होगी प्रिंटर.प्रिंट बिटमैप() के साथ एक छवि के रूप में बाइट्स। इस तरह प्रिंटर उचित डेटा प्रिंट करने के लिए इसे तैयार करने के लिए उचित आदेश प्राप्त कर रहा है। आपको PHP में प्रिंट करना चाहते हैं और Arduino को भेजने के लिए आपको कुछ मेटाडेटा बनाने की आवश्यकता होगी। एक JSON प्रारूप इस प्रकार दिखाई देंगे:

{"reciept": [ 
    { 
    "type": "text", 
    "style": "bold", 
    "value": "Thank you for your purchase" 
    }, 
    { 
    "type": "bitmap", 
    "pos": "center", 
    "value": ".... binary data ..." 
    } 
]} 

अब अपने Arduino स्केच जब बाइट्स व्यक्तिगत रूप से भेजने के लिए पाठ और जब एक बिटमैप के रूप में काफी मात्रा में डेटा भेजने के रूप में समझ जाएगा।

एक अधिक कॉम्पैक्ट प्रारूप लाइन का उपयोग कर सकते क्षेत्रों के बीच एक को तोड़ने के रूप में फ़ीड:

F|bold 
T|Thank you for shopping with us\r 
P|Center 
B|...binary data (with \r escaped)... \r 

या, आप ज्यादा की सामग्री-लंबाई हेडर की तरह बाइनरी डेटा से बचने से बचने के लिए और प्रत्येक सेगमेंट डेटा की मात्रा भेज सकते हैं HTTP

F4|boldT32|Thank you for shopping with us\rP6|CenterB3000|...binary data... 
+0

प्रिंटबिटमैप सिर्फ दृश्यों के पीछे लिख रहा है। प्रिंटिंग बोल्ड इत्यादि सही तरीके से काम करता है, इसलिए इसे बाइट्स के रूप में भेजे गए आदेशों को सही ढंग से व्याख्या करना चाहिए (पैक के लिए PHP में देखें)। मुझे लगता है कि मेरे पास सिर्फ मेरा छवि डेटा गलत है। – Dachande663

+0

क्या आप निश्चित हैं कि बाइट भेजने के साथ कोई समय समस्या नहीं है, फिर 4 बार बनाम 4 बाइट्स भेजकर प्रतीक्षा कर रहे हैं और फिर एक बार प्रतीक्षा कर रहे हैं? लिखना बाइट्स (ए, बी, सी, डी) बिल्कुल लिखने के समान नहीं हो सकता हैइट्स (ए); writeBytes (ख); writeBytes (ग); writeBytes (घ); मैं अभी भी थर्मल लाइब्रेरी के सभी सी को PHP में फिर से कार्यान्वित करने की कोशिश नहीं करूंगा ताकि आर्डिनो बाइट्स का सिर्फ एक पाथस्ट्रू हो - यह काम कर सकता है लेकिन यह समय के मुद्दों के साथ समाप्त हो सकता है। मुझे लगता है कि इसे डीबग करने का एक तरीका है Arduino उदाहरणों में से कुछ लेना और उन्हें शुद्ध लेखन बाइट्स (ए) कॉल के रूप में दोबारा लिखना है। यदि यह काम करता है, तो यह डेटा के साथ एक समस्या है। – chugadie