Posts by nurazur

    du hast einen Punkt. nach 40 Jahren Praxis in C Programmierung hab ich wieder mal was gelernt :).



    weil ein Überlauf bei ``<<`` bei `int` undefiniertes Verhalten ist, während bei `unsignet int` die Bits einfach rausgeschoben werden/verloren gehen.

    Das steht so nicht im Standard, jedenfalls nicht in meinem (damals ANSI C, also K&R, heute als C89 bzw C90 Standard bezeichnet).



    Im C Standard steht:

    Quote

    "Die shift-Operatoren << und >> werden von links nach rechts zusammengefasst. Bei beiden Operatoren muss jeder Operand ein Integer-Wert sein und Integer-Erweiterung findet statt. Der Resultattyp ist der Typ des erweiterten linken Operanden."

    Jetzt kommts:

    Quote

    Das Resultat ist undefiniert, wenn der rechte Operand negativ ist oder wenn der Wert des rechten Operanden nicht kleiner ist als die Länge des linken Operanden in Bits.

    Demnach müsste es korrekt (1L<<16)-1 heissen, das u verstehe ich zwar jetzt, ergibt aber keinen Sinn. Zur Sicherheit koennte man ja (1UL<<16)-1 schreiben.


    Da aber die Typ-Erweiterung im Kompiler automatisch abläuft, ist der Zusatz nicht notwendig. Eine Schiebeoperation um 16 bits sagt dem Kompiler dass der linke Operand mindestens 17 bits haben muss (laut ANSI C Standard), also erweitert er den Typen auf long. Ob das jetzt signed oder unsigned ist ist egal.

    Da müsste man dann aber wohl ``(1L << 16) - 1`` schreiben, denn ein ``1u << 16`` ist entweder selbst schon undefiniert oder das abziehen von 1 von der resultierenden nicht vorzeichenbehafteten 0 ist es.

    stimmt. Da es aber funktioniert gehe ich davon aus dass der Compiler merkt dass der Ausdruck (1<<16) ein long ist. Das 'u' hinter der 1 verstehe ich sowieso nicht, das besagt dass die 1 ein unsigned int ist. Aber der Wert 1 kann ja nicht negativ sein, weil eine Konstante im Source Code immer erst mal als int interpretiert wird.

    Ich weiss jetzt nicht ob ein Compiler bei einer 8 Bit CPU bei 0xffff meckern wuerde. Erwarten wuerde ich es jedenfalls.

    Arduino Uno, Nano oder Pro-Mini haben eine 8-bit CPU, und der C++ Compiler avr-g++ erlaubt int (16 bit) und long (32 bit) und float (32 bit) Operationen ohne zu meckern. 0xFFFF wird klaglos abgearbeitet, wenn man eine Konstante als long (32 bit) Wert bestimmen will, setzt man ein 'L' dahinter, also z.B. 0xFFFFL, Der Kompiler würde 0xFFFF als int erkennen, aber mit dem L dahinter wird es ein long. Manchmal kann das sinnvoll sein.


    Ich arbeite ausschliesslich mit C++ Compilern, und in C gibt es die minimale Konvention char = 8bit, short=16 bit, long=32 bit, float = 32 bit. Insofern ist eine Konstante 0xFFFF 100% portabel. Das war schon beim Intel 8051 so.

    Die Datentypen int , bool und double sind prozessorabhängig. Beim Arduino Uno z.B. ist int das selbe wie short und double  ist das selbe wie float.


    Assembler auf einer 8-bit Architektur ist eine komplett andere Baustelle, da muss sich der Programmierer selbst um die Datentypen kümmern. Da wird eine Fliesskomma Operation zur echten Herausforderung. Aber zum Glück gibts ja Compiler!

    wenn man die Ausführungszeit optimieren will

    ... dann hätte ich gleich 0xFFFF geschrieben, weil man ja nicht weiss (also ich zumindest nicht) was der Compiler aus (1u<<16)-1 macht.


    Ein guter Compiler merkt dass er die Rechnung bereits zur Kompilierzeit machen kann und tut das dann auch. Ein weniger guter wird die Schiebeoperation und die Subtraktion in Assember Code übersetzen.

    Würde mich mal interessieren was der gcc Compiler draus macht. Da gibts ne Kommandozeilen Option mit der man den Assembler Code angezeigt bekommt. Ist mir aber grad entfallen welche.

    Ich interpretiere es so. Nehme 1 schiebe 16 mal nach links und ziehe 1 ab???

    genau. Mit Klammern.



    ohne Klammern kommt 8000 Hex rauß

    genau, weil - Vorrang vor << hat, also "ziehe 1 von 16 ab und schiebe eine 1 (16-1) mal nach links = 2 hoch 15 = 0x8000


    Aber vielleicht kommt der Code auch einem Register in Assembler nahe.

    Das ist das Geniale an C: die Sprache ist sehr nahe an der Hardware gebaut und dennoch erlaubt sie genug Abstrahierung von der Maschine so dass Menschen damit umgehen koennen. Das heisst, wenn man C programmiert bekommt man sehr effizienten Code. Ein guter Compiler ersetzt in den allermeisten Fällen die Assembler-Programmierung.

    Ganz klar Punkt vor Strich und somit ist << auch ein Punkt??


    Jetzt hab ich doch tatsächlich meinen alten Kernighan/Ritchie aus dem Regal genommen um zu sehen was Vorrang hat.

    In der Tat, + und - hat Vorrang über << und >>, also MUSS man die Klammern setzen.


    BTW: Kernighan/Ritschie, "Programmieren in C" ist ein Buch der Erfinder/Entwickler von C, und auch wenn sich die Sprache mit den Jahrzehnten extrem weiter entwickelt hat ist es ein absolutes Standardwerk, das jeder C/C++ Programmierer haben sollte, und mindestens einmal durchgearbeitet haben sollte. Die Syntax hat sich nicht verändert.

    a) weil er's kann?

    b) weil er grad nicht weiss was dezimal 2 hoch 16 minus 1 ist ?

    c) um den geneigten Leser des Source Codes zu verwirren?

    d) um darzustellen wie gut er in Integer-Mathematik ist?

    e) um zu beweisen wie gut er C gelernt hat?

    f) weils wurscht ist, der Compiler rechnet es dann schon aus (wenns ein guter Compiler ist)?

    Da trifft das geschriebene zu.

    stimmt, habe ich auch nicht kritisiert. Das ist andererseits nicht im entferntesten der Arbeitsbereich wo wir einen Papst-Lüfter ansteuern wollen. Warum wolltest du das Beispiel mit maximalem Kollektorstrom??


    Bevor du hier den Schlaumeier miemst

    Ich schlage vor du lasst solche Seitenhiebe einfach sein, das bringt niemandem was und wir wollen uns hier respektvoll miteinander auseinandersetzen.

    Ich zumindest.


    Ich habe Elektronik studiert

    Tja da sind wir ja schon 2, bei mir war das zu einer Zeit als wir im Praktikum noch Transistorkennlinien von Hand durchmessen mussten bzw. durften.


    Hier nochmal einmal ein Beispiel mit einem 47 Ohm Lastwiderstand, das ergibt etwa 250mA Kollektorstrom

    Wie zu sehen verläuft die Kurve hier viel flacher und der Transitor geht bereits bei etwa 200yA Basisstrom in die Sättigung.


    Der BC337 hat maximal ein hFE von 600, je nach Gruppe. Wenn ich hFE=600 ansetze komme ich bei 0,2mA Basistrom auf MAXIMAL 120mA Kollektorstrom, aber da ist der Transistor garantiert NICHT in Sättigung. Da stimmt was um Faktor 10 nicht.

    Ich hab oben meinen Beitrag #45 editiert und den Verdacht geäussert dass an dem Diagramm links oben die x-Achse nicht stimmt.

    Ich hab ein Datenblatt von ST Electronics gefunden aber da ist das Diagramm nicht drin.

    Im Schalterbetrieb wird der Transitor mit maximalen Basisstrom angesteuert.

    Das würde ich so nicht unterschreiben. Es kommt darauf an den Transistor in Sättigung zu bekommen, und das geht ganz einfach indem man dem Transistor weniger Kollektorstrom zur Verfügung stellt, als dessen Stromverstärkung eigentlich ermoeglicht.


    Beispiel:

    Hier fliesst bei einem Basistrom von ca. 1mA ein Kollektorstrom von ca. 10mA, was einer Stromvertärkung von ca. 10 entspricht. Das hFE des Transistors liegt aber irgendwo zwischen 100 und 650 (laut Datenblatt des BC337), d.h der Transistor versucht einen sehr viel hoeheren Strom einzustellen als er bekommt, deswegen geht er in Sättigung. Das ist genau der Effekt den wir haben wollen, und das geht auch bei sehr kleinen Stroemen! Du kannst in obigem Beispiel auch einen 43k Basiswisderstand und einen 10k Kollektorwiderstand nehmen, und der Transistor geht immer noch in Sättigung.

    Maximalen Kollektorstrom will ich doch gar nicht erst erreichen, schade um die Energieverschwendung. Kommt halt auf die Anwendung an.


    Hier noch zwei dazu passende Diagramme aus dem BC337 Datenblatt, zur Kenntnisnahme und ggf. Studium:



    was du hier behauptest wäre ein hfe von ca. 1000 und das kann definitiv nicht stimmen.

    das ist mir zwar auch aufgefallen, ist aber eigentlich egal wenn man die Schaltung so auslegt dass der Transistor in Sättigung gehen muss. Du nimmst einen Faktor 3 bis 5, damit geht auch der schlechteste Transistor in Sättigung, ich nehme lieber einen Faktor 10, aber egal.


    Ich hab mir das Diagramm mit den Kennlinien das Delta09 zeigt nochmal genau angesehen, und --- ich kanns fast nicht glauben --- im Diagramm links oben stimmt die x-Skala nicht, d.h. das Diagramm ist falsch.

    Wenn es richtig wäre, bekomme ich bei IB=0.8mA und VCE=1V einen Kollektorstrom von 700mA. Gehe ich nach rechts, beginnen die Kennlinien aber erst bei 1mA IB, und damit bekomme ich bei VCE=1V vielleicht 100mA aber nicht mehr. Wenn ich jetzt die x-Skala mit Faktor 10 multipliziere, also aus 0.2mA werden 2mA, dann stimmt das Diagramm wieder. Daher kommt auch der Verstärkungsfaktor von >1000 der uns aufgefallen ist und einfach nicht stimmen kann.


    jar bitte sag mir dass ich total falsch liege

    Delta09 wo hast du das Diagramm her??


    Fehler in Datenblättern sind selten, aber sie kommen vor.

    Die Sättigungsspannung ist die Spannung Uce

    Ein Transistor ist ein Stromverstärker. Er verstärkt den Strom von B nach E (Ibe) in einen Strom von C nach E, also Ice, wobei die Stromvertärkung im Datenblatt angegeben ist und typischerweise 100 bis 200 beträgt, also Ice = h *Ibe.

    Sättigung entsteht dann, wenn die Verstärkung h aufgrund der externen Schaltung nicht erreicht werden kann, also Ice < h * Ibe. Diesen Fall wünscht man sich bzw. erzwingt man wenn man etwas schalten will. Die Spannung Uce wird in Sättigung minimal, und ist abhängig vom Strom Ice. Je kleiner dieser Strom, desto kleiner die Spannung Uce. Wenn das das ist was du als Sättigungsspannung bezeichnest sind wir auf einer Linie, aber du hast es echt missverständlich dargestellt. Die Spannung Uce ist die Spannung zwischen Kollektor und Emitter, und sonst nichts.

    Es ist mir immer noch unverständlich, wie du 1 oder 1,5 oder 2 Volt Basisspannung erreichen willst.

    ganz einfach: indem du die Spannung anlegst. Was dann passiert steht auf einem anderen Blatt, besonders wenn man PWM anlegt (was eine Wechselspannung mit Gleichanteil ist). Als "absolute maximum rating" ist oft eine Ube Spannung von 5V angegeben, aber das sagt ja nicht wie lange der Transistor das aushält. Ich gehe mal von Millisekunden aus.


    Irrtum - das hab ich Delta schon gestern Abend gegen Mitternacht privat geschrieben.

    gut, dann hätte ich mir meinen Post ja sparen koennen wenn ich das gewusst hätte. Ich finde das ehrlich gesagt gegenüber den anderen Forenschreibern etwas unglücklich, egal was sie schreiben.


    Du könntest auch mal die UCE und UBE bei verschiedenen Pulsweiten (z.B. 0/25/50/100%) messen. Die Spannungswerte müssen sich mit der Pulsweite ändern (UBE steigt von 0 bis max. ca. 0,7V, UCE sinkt von UREF gegen ca. 0,2V)

    Ich glaube das ist ziemlich tricky. Wir haben es hier mit PWM zu tun, also braucht der T.E. ein true RMS Voltmeter und muss auf AC stellen, oder? Was auf DC rauskommt - keine Ahnung! Und dann muss das Messgerät auch noch mit Wechselspannungen im 5kHz Bereich zurecht kommen, und das traue ich meinem Fluke Multimeter nicht zu.

    Also ich weiss echt nicht was mein Multimeter kann oder macht. Die PWM hier ist eine Wechselspannung mit Gleichanteil. Wie messen? Also ich weiss es echt nicht. Klar dass das Multimeter was anzeigt. Aber was? (2. Grundregel der Elektronik: wer viel misst misst Mist)


    Deswegen habe ich in #29 auch eine STATISCHE Messung vorgeschlagen.

    Also ich würde jetzt wie folgt vorgehen (in der Reihenfolge von 1 bis 3)


    1. Die PWM Frequenz nach Datenblatt auf zwischen 2000 und 5000Hz einstellen, ich würde in die Mitte gehen und auf 3500Hz ändern, im Python Code stehen 1500 Hz das ist ausserhalb der Spec. ( RTFM hat dir schon 2 x den Hinweis gegeben)


    2. wenn das immer noch nicht funktioniert, würde ich den Transistor statisch testen, wenn 0V am GPIO anliegen müsste die Spannung am PWM Eingang des Luefters 10 -12V sein. Wenn der GPIO auf HIGH ist, müsste die Spannung am Kollektor irgendwo zwischen 50 und 200mV liegen (je nachdem wieviel Strom durch den Kollektor fliesst). Wenn das passt, ist immer noch nicht gesagt dass der Transistor WIRKLICH in Ordnung ist, aber es ist dann sehr wahrscheinlich.


    3. Es gibt auch dynamische Effekte wenn ein Transistor sagen wir, angeschlagen ist. Und es gibt ALLES zwischen "tot" und "voll funktionstüchtig" (hier sprechen 50 Jahre Erfahrung mit Transistoren). Solltest du noch einen weiteren neuen Transistor zur Hand haben, würde ich ihn austauschen. Mit Vorwiderstand 4.7 kOhm kann dem Transistor eigentlich nichts passieren, ausser, wie gesagt, du verpolst C und E.

    Das ist falsch!

    Vorsicht mit solchen Behauptungen, bitte.

    Wenn Kollektor und Emitter vertauscht werden tut sich gar nichts

    da täuschst du dich leider gewaltig. Ein NPN Transistor besteht aus 3 verschieden dotierten Halbleiterschichten. Wenn du mal die Basis-Kollektor Strecke isoliert betrachtest, bekommst du eine PN Schicht = Diode. Wenn du also einen Strom von Basis zum Kollektor schickst, stellt sich tatsächlich ein "Transistoreffekt" ein, so dass Strom vom Emitter zum Kollektor fliesst. Probier es aus! Natürlich ist dieser Betrieb weder spezifiziert noch anzuraten.

    Sachen gibts... ;)

    Der Strom muss dann so groß sein, dass URI erfüllt ist. Und das wäre ziemlich groß. Und dann wird der Transistor durchbrennen. Im praktischen Fall dieses Threads wird das aber kaum passieren.

    genau. Weil vorher wahrscheinlich der GPIO des Raspberry Pi über den Jordan geht...


    Ich denke es ist klar dass die Schaltung die Rene Cherry vorschlägt mit ziemlicher Sicherheit einen Schaden verursachen wird, entweder beim Transistor, oder beim GPIO oder beiden. Es ist auch klar dass der Transistor bzw. GPIO, auch wenn beide das zeitweise zu überleben scheinen , weit ausserhalb jedweder Spezifikation bzw. vernünftigem oder kontrolliertem Arbeitsbereich betrieben wird/werden. Datenblätter haben durchaus einen Sinn. Ich hab allerdings jede Menge Verständnis für Leute die Datenblätter von Transistoren nicht verstehen. Die Dinger sind komplex. 2V BE Spannung ist - so sorry to say that- weit ausserhalb dessen was sich die Entwickler in der Anwendung vorgestellt haben.


    Also lieber Rene Cherry, bitte schalte einen Vorwiderstand zwischen GPIO des Raspberry und Basis des Transistors. Irgendwas zwischen 1.5 kOhm und 10kOhm sollte funktionieren. Die 330K am Collector nach +12V sind, denke ich, nicht notwendig, wie VeryPrivat bereits schrieb. Der Transistor kann dann nicht kaputt gehen, ausser du machst einen Anschlussfehler. Wenn man beispielsweise C und E aus Versehen vertauscht, funktioniert der Transistor im Prinzip auch! Nur halt nicht nach Datenblatt, und man muss mit seltsamen Effekten rechnen.

    Warum?

    Die versuchen zur Zeit einen neuen Software Stack zu implementieren den sie'V3' nennen, und der Umstieg von V2 auf V3 verläuft chaotisch, weil die beiden Versionen nicht kompatibel zueinander sind. Zur Zeit laufen beide Versionen parallel, aber TTN will die Leute bis Ende des Jahres zwingen auf V3 umzusteigen. Dazu muss man seine bereits existierenden Nodes neu konfigurieren und in V3 importieren, aber das funktioniert in vielen Fällen einfach nicht. Ein Kumpel von mir kämpft seit Wochen eines seiner Nodes in V3 zu integrieren, ohne Erfolg. Ich selbst habs noch gut, nicht zu viele Nodes im Feld und ich kann den Umstieg mittels Firmware Aenderung abfedern. Hätte ich einen breiten Kundenstamm hätte ich mit TTN jetzt die A-Karte. Alle Nodes neu flashen...

    Manchmal kehren halt neue Besen schlechter als alte.

    Von der LoRa Technologie und dem Community Gedanken von TTN bin ich aber nach wie vor absolut überzeugt, Geniale Technik, extreme Reichweiten, kostenloses Netzwerk... gut, ich muss mein eigenes Gateway unterhalten weil sonst keins in der Nähe ist. Aber in vielen Gegenden ist das Netzwerk schon recht dicht.

    naja, sieht nach Bastelei aus. Interessant ist dass sie die Sensor Einheit an der Stalltür befestigen, das würde ich so niemals machen. Erstens bewegt sich mit der Tür die Antenne mit, da weiss man nie ob man gerade gute Abstrahleigenschaften hat oder halt suboptimale. Ausserdem erscheint mir der mechanische Aufbau des Magnetschalters alles andere als robust zu sein. So eine Stalltür kann schon mal ordentlich zuknallen. Soll jeder für sich selbst entscheiden. ob er/sie/es 13 EUR dafür ausgeben will.


    Die TiNo's können mit LoRa ausgerüstet werden und auch LoRaWAN ist möglich, das hab ich nur noch nicht öffenlich gemacht mangels Zeit.

    Der Plan ist ein "extreme-lowcost" LoRaWan Sensor, ich muss derzeit aber nachdenken weil die Chippreise explodieren und meine ursprüngliche Begeisterung für das TheThingsNetwork (TTN) Anfang des Jahres einen heftigen Dämpfer abbekommen hat.

    aber dein Programmcode ist reichlich ineffizient

    um das mal wieder auf eine sachliche Ebene zu bringen, hab ich hier eine Story zum Thema Effizienz:

    Ich hatte mal die Aufgabe den Spaghetti-Code eines Monster-Programms einer Laborratte in ein C++ Testprogramm umzuschreiben das 'effizient' in der Produktion verwendet werden kann. Und wenn ich effizient sage, meine ich dass jede Sekunde in der Produktion zählt und kostet. Nachdem wir das Programm 1:1 von HP Vee in C++ umgewandelt hatten waren wir überrascht wie wenig schneller der Code in C++ lief... nur wesentlich zuverlässiger. Mein Kollege hat sich dann die Mühe gemacht die reinen Berechnungen des C++ Codes zusammenzurechnen. Ich war geflasht, auf unserem PC war die reine Rechenleistung nur 0.1 Sekunde auf 5 Minuten Testzeit! Da wussten wir dass wir nicht beim Programmierstil ansetzen mussten sondern an den Algorithmen. Eine Sauarbeit! Wir haben dann die Testzeit auf 30 Sekunden verkürzen koennen, was ein Faktor 10 ist. Eine immense Kostenersparnis, wenn man 100000 St. eines Produkts pro Woche herstellen muss.


    Ich verstehe nicht warum du die "Effizienz" des Programmcodes von jemandem, der sich ganz klar als nicht-professioneller Programmierer erklärt, kritisierst.

    BTW, das Zitat oben kommt bei mir eindeutig als Kritik rüber, auch wenn du das jetzt wieder nicht so verstanden haben willst.

    Danke für die Links, was ich gesucht habe bzw. was mich interessiert habe ich gefunden. Du hast das ja gut dokumentiert, nur die beiden Links haben halt gefehlt.


    Willst du das Projekt kommerzialisieren? Wenn nicht koennte es dir ja egal sein den Code zu veroeffentlichen.