Wyświetlanie stanu z pamięci komputera na wyświtlacz LCD (Arduino)

 6 Lipiec 2011 Arduino 
Artykuł przedstawia w jaki sposób można wyświetlać dane z komputera na inny interface niż monitor przy użyciu Arduino.

Wyświetlanie informacji w taki sposób ma bardzo dobre zastosowanie w chili gdy nie wszystkie informacje są wyświetlane na ekranie (np procent życia w danej grze), gdy nie chcemy, żeby monitor cały czas się palił, a zależy nam na bieżąco monitorowanie jakiś informacji/procesów (np ilość maili w skrzynce, procent ściągniętego pliku).

Przykładowe filmiki przedstawiają poglądowe zastosowanie układu.
Oczywiście zastosowań może być wiele, wiele więcej.


saper_arduino

Podłączenie

Potrzebne będą:
  • Arduino UNO
  • 2x Rejestr przesuwny typu SIPO (Serial-In, Parallel-Out) o 8 wyjściach równoległych w tym przypadku 74HC595
  • 2x wyświetlacz LED o wspólnej adnodzie
  • 2x rezystor 220 ohm
  • kabel USB
  • kabelki podłączeniowe
uklad do sterowania diodami LED
Rejestr przesuwny


Uwaga, na układzie poniżej jest poprzemieniane połączenie z arduino. Poprawne jest wyżej.Kondensator dołączony do układu nie jest potrzebny...

LED ze wspólną anodą
LED ze wspólną anodą

Podłączenie LED z Rejestrem przesuwnym (podłączenie dla obu LED jest takie samo).

Kod dla Sapera

Kod jest napisany w pythonie. Do kompilatora potrzebne są dodatkowe 2 moduły: WMI i pyserial.
Informacje, którą chcemy wyświetlić na naszym LED znajduje się w pamięci komputera. Żeby ją znaleść (a konkretnie adres pamięci) polecam program Cheat engine. Mając adres pamięci, w kodzie musimy podmienić nazwę procesu (w saperze name="winmine.exe") oraz adress (w saperze 0x100579C, 2) gdzie 0x100579C jest to adres pamięci, w którym zapisana jest ilość sekund, a 2 jest to ilość bajtów zajmująca pamięć.
[ python ] winmine.pyZaznacz cały
#! c:\python26\python.exe
 
import ctypes, time
import ctypes.wintypes
from ctypes import *
import wmi
import serial
 
c = wmi.WMI ()
 
ser = serial.Serial('COM5', 9600)
 
PID = 0
def getPID():
    global PID
    for process in c.Win32_Process (name="winmine.exe"):
        PID = process.ProcessId
 
getPID()
kernel32 = ctypes.wintypes.windll.kernel32
 
# Various access flag definitions:
class Access:
    DELETE      = 0x00010000
    READ_CONTROL= 0x00020000
    SYNCHRONIZE = 0x00100000
    WRITE_DAC   = 0x00040000
    WRITE_OWNER = 0x00080000
    PROCESS_VM_WRITE = 0x0020
    PROCESS_VM_READ = 0x0010
    PROCESS_VM_OPERATION = 0x0008
    PROCESS_TERMINATE = 0x0001
    PROCESS_SUSPEND_RESUME = 0x0800
    PROCESS_SET_QUOTA = 0x0100
    PROCESS_SET_INFORMATION = 0x0200
    PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
    PROCESS_QUERY_INFORMATION = 0x0400
    PROCESS_DUP_HANDLE = 0x0040
    PROCESS_CREATE_THREAD = 0x0002
    PROCESS_CREATE_PROCESS = 0x0080
 
 
 
def read_process_mem(pid, address, size):
    """Read memory of the specified process ID."""
    buf = ctypes. create_string_buffer(size)
    gotBytes = ctypes.c_ulong(0)
    h = kernel32.OpenProcess(Access.PROCESS_VM_READ, False, pid)
    try:
        if kernel32.ReadProcessMemory(h, address, buf, size, ctypes.byref(gotBytes)):
            return buf
        else:
            # TODO: report appropriate error GetLastError
            raise Exception("Failed to access process memory.")
    finally:
        kernel32.CloseHandle(h)
 
def set_LCD(t):
    t = str(t)
    #print t
    if len(t)==3:
        t=t[1]+t[2]
    if len(t)==0 or len(t)>3:
        t="00"
    if len(t)==1:
        t="0"+t
    if len(t)==2:
        t=""+t
    ser.write('X'+t+"\0")
 
def mineTime():
    try:
        r = read_process_mem(PID, 0x100579C, 2)
        return int(r.value.encode('hex'), 16)
    except :
        return 0
    #return
while 1:
    #print mineTime()
    set_LCD(mineTime())
    time.sleep(0.1)

Kod dla gry Call of duty MW2

[ python ] COD2.pyZaznacz cały
#! c:\python26\python.exe
 
import ctypes, time
import ctypes.wintypes
from ctypes import *
import wmi
import serial
 
c = wmi.WMI ()
 
ser = serial.Serial('COM5', 9600)
 
PID = 0
def getPID():
    global PID
    for process in c.Win32_Process (name="iw4sp.exe"):
        PID = process.ProcessId
 
getPID()
kernel32 = ctypes.wintypes.windll.kernel32
 
# Various access flag definitions:
class Access:
    DELETE      = 0x00010000
    READ_CONTROL= 0x00020000
    SYNCHRONIZE = 0x00100000
    WRITE_DAC   = 0x00040000
    WRITE_OWNER = 0x00080000
    PROCESS_VM_WRITE = 0x0020
    PROCESS_VM_READ = 0x0010
    PROCESS_VM_OPERATION = 0x0008
    PROCESS_TERMINATE = 0x0001
    PROCESS_SUSPEND_RESUME = 0x0800
    PROCESS_SET_QUOTA = 0x0100
    PROCESS_SET_INFORMATION = 0x0200
    PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
    PROCESS_QUERY_INFORMATION = 0x0400
    PROCESS_DUP_HANDLE = 0x0040
    PROCESS_CREATE_THREAD = 0x0002
    PROCESS_CREATE_PROCESS = 0x0080
 
 
 
def read_process_mem(pid, address, size):
    """Read memory of the specified process ID."""
    buf = ctypes. create_string_buffer(size)
    gotBytes = ctypes.c_ulong(0)
    h = kernel32.OpenProcess(Access.PROCESS_VM_READ, False, pid)
    try:
        if kernel32.ReadProcessMemory(h, address, buf, size, ctypes.byref(gotBytes)):
            return buf
        else:
            # TODO: report appropriate error GetLastError
            raise Exception("Failed to access process memory.")
    finally:
        kernel32.CloseHandle(h)
 
def set_LCD(t):
    t = str(t)
    #print t
    if len(t)==3:
        t=t[1]+t[2]
    if len(t)==0 or len(t)>3:
        t="00"
    if len(t)==1:
        t="0"+t
    if len(t)==2:
        t=""+t
    ser.write('X'+t+"\0")
 
def mineTime():
    try:
        r = read_process_mem(PID, 0x007625C0, 2)
        return int(r.value.encode('hex'), 16)
    except :
        return 0
    #return
while 1:
    #print mineTime()
    set_LCD(mineTime())
    time.sleep(0.1)

Kod Arduino, dla obu przypadków

[ csharp ] _2xDidtal_python.pdeZaznacz cały
//Pin connected to ST_CP of 74HC595
int latchPin = 13;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;
 
// Second ST_CP
//Pin connected to ST_CP of 74HC595
int latchPin2 = 7;
//Pin connected to SH_CP of 74HC595
int clockPin2 = 6;
////Pin connected to DS of 74HC595
int dataPin2 = 5;
 
#include <stdlib.h>     // needed for atoi, atoi = ~strToInt
char buffer[5];   //Otrzymywane dane
int received;      // otrzymany bit
 
//holder for infromation you're going to pass to shifting function
byte data = 0;
 
int myInt, myInt2;
int digitalArray[10];
 
void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
 
  pinMode(latchPin2, OUTPUT);
  pinMode(clockPin2, OUTPUT);
  pinMode(dataPin2, OUTPUT);
 
  Serial.begin(9600);	// opens serial port, sets data rate to 9600 bps
  received = 0;
  buffer[received] = '\0';
  digitalWrite(latchPin, HIGH);
  digitalWrite(latchPin2, HIGH);
  myInt = 170;
  myInt2 = 0;
}
 
 
void blinkArt3(int n, int d) {
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, B00011000);
  digitalWrite(latchPin, HIGH);
  delay(200);
 
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, B10000001);
  digitalWrite(latchPin, HIGH);
  delay(200);
 
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, B01000010);
  digitalWrite(latchPin, HIGH);
  delay(200);
 
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, B00100100);
  digitalWrite(latchPin, HIGH);
  delay(200);
}
 
void loop() {
  // send data only when you receive data:
   if (Serial.available() > 0)
    {
 
          buffer[received++] = Serial.read();
          if (buffer[0]!='X'){received = 0;}
          else{
  	  buffer[received] = '\0';
  	  if (received >= (sizeof(buffer)-1))
  	  {
            digitalArray[48]=B1000000; // 0
            digitalArray[49]=B1111001; // 1
            digitalArray[50]=B0100100; // 2
            digitalArray[51]=B0110000; // 3
            digitalArray[52]=B0011001; // 4
            digitalArray[53]=B0010010; // 5
            digitalArray[54]=B0000010; // 6
            digitalArray[55]=B1111000; // 7
            digitalArray[56]=B0000000; // 8
            digitalArray[57]=B0010000; // 9
            buffer[0]='0';
        	   myInt = digitalArray[buffer[1]];
                   myInt2 = digitalArray[buffer[2]];
               // Serial.println(buffer);
 
                Serial.print("1: ");
 
                Serial.println(digitalArray[buffer[1]]);
                buffer[1] = 0;
                buffer[2] = 0;
                 /* digitalWrite(latchPin, LOW);
                  shiftOut(dataPin, clockPin, MSBFIRST, myInt);
                  digitalWrite(latchPin, HIGH);
      */
                received = 0;
            }
          }
 
   }
                  digitalWrite(latchPin, LOW);
                  shiftOut(dataPin, clockPin, MSBFIRST, myInt);
                  digitalWrite(latchPin, HIGH);
 
                  digitalWrite(latchPin2, LOW);
                  shiftOut(dataPin2, clockPin2, MSBFIRST, myInt2);
                  digitalWrite(latchPin2, HIGH);
//Serial.print("I received: ");
}

Dołączone pliki


Przeczytaj także

Kategorie