einzelne Bits setzen
-
ich hab eine Relaiskarte mit 8 Eingängen, die ich ansteuere. Dazu gibt es eine Funktion der dll des Herstellers die lautet:
QAPIExtWriteDO8(handle, deviceNum, byte, 0);
Interessant ist hier der Parameter "byte" der ein 8Bit Wort erwartet als Ganzzahl. Bisher hab ich nur ein Relais verwendet und ich hab einach einen Wert genommen bei dem das entsprechende Bit gesetzt wird. Da ich nun mehrere Geräte mit der Relaiskarte ansteuern will geht das natürlich nicht. Hab mir eine einfache Klasse zu dem Gerät geschrieben (Siehe Code unten). Wie setze ich einzelne Bits?
class Quancom { private: ULONG handle; short byte; public: bool SwitchRelais(short relaisNum); Quancom(); }; Quancom::Quancom() : byte(0) { //TODO: Hier Ihren Quelltext einfügen } //--------------------------------------------------------------------------- bool Quancom::SwitchRelais(short relaisNum) // Relais als 8Bit-Wert { int deviceNum = -1; //Karte suchen for (int device=0; device<7; device++) { ULONG handleTemp = QAPIExtOpenCard(USBREL8LC, device); if (handleTemp != 0) { handle = handleTemp; deviceNum = device; } } byte = byte | relaisNum; // so gehts nicht wie merke if (deviceNum == -1) return false; else { QAPIExtWriteDO8(handle, deviceNum, byte, 0); return true; } }
Ich will nun als Parameter einfach die Nummer des Relais eintragen (1-8).
-
//setzen byte = byte | (1<<relaisNum); //löschen byte = byte & ~(1<<relaisNum); //flipfloppen byte = byte ^ (1<<relaisNum);
-
danke. Hab 2 Funktionen gemacht für on und off:
void Quancom::SwitchRelaisOn(short relaisNum) // Relais als 8Bit-Wert { byte = byte | (1<<relaisNum); QAPIExtWriteDO8(handle, deviceNum, byte, 0); } void Quancom::SwitchRelaisOff(short relaisNum) // Relais als 8Bit-Wert { byte = byte & ~(1<<relaisNum); QAPIExtWriteDO8(handle, deviceNum, byte, 0); }
es funktioniert jedenfalls so. Oder kann man das vll besser machen in einer Funktion?
-
rudpower schrieb:
Oder kann man das vll besser machen in einer Funktion?
Also man kann es in eine Funktion machen.
void Quancom::SwitchRelais(short relaisNum,bool an){ if(an) byte = byte | (1<<relaisNum); else byte = byte & ~(1<<relaisNum); QAPIExtWriteDO8(handle, deviceNum, byte, 0); }
oder um Vorwegzunehmen, was gleich so sicher kommt (und für mich weit unten auf der Codehübschigkeitsskala rangiert)
void Quancom::SwitchRelais(short relaisNum,bool an){ byte = an ? byte | (1<<relaisNum) : byte & ~(1<<relaisNum); QAPIExtWriteDO8(handle, deviceNum, byte, 0); }
aber ist die dann auch besser zu bedienen? Keine Ahnung, das mußt Du selber entscheiden.
-
void Quancom::SwitchRelais(short relaisNum) // Relais als 8Bit-Wert { byte = byte ^ (1<<relaisNum); QAPIExtWriteDO8(handle, deviceNum, byte, 0); }
zum Switchen kannst du einfach ^ nehmen (steht ja auch schon 3 Posts obendrüber)
greetz KN4CK3R
-
vielen Dank, funktioniert prima. Wieder was gelernt^^
-
jetzt habe ich ein Problem. Schalte ich zB das erste Relais und danach das zweite Relais, schaltet das erste Relais zurück. Umgekehrt ist es genauso
Edit: zum Verständnis: ist es korrekt, dass die Zeile (1<<relaisNum) nur bewirkt, dass nur 1 bit genommen wird? Will ich das 1. Relais schalten soll ja das 1. Bit gesetzt werden also nehm ich 0 als relaisNum. Aus (1 << 0) wird 00000001. Ich denk das ist richtig so.
Jetzt schalt ich ein und muss das 1. Bit setzen: 00000000 | 00000001
--> byte = 00000001. Somit ist das 1.Relais geschaltet.
Nun setz ich das 2. Relais mit 00000001 | 00000010 --> 00000011Nun sollten ja eigentlich beide Relais an sein.
-
Problem gelöst. Da die Funktion in einer Klasse ist muss die Variable byte als static deklariert werden, da sie sonst bei der Instanzierung immer wieder 0 ist.
-
Static Variablen sind oft unschön, kannst du den aktuellen Status nicht durch
QAPIExtReadDO8 (oder so) lesen, den gelesenen Wert anpassen und dann zurückschreiben?