File indexing completed on 2024-05-19 09:39:03
0001 /*************************************************************************** 0002 * Copyright (C) 2003 by David Saxton * 0003 * david@bluehaze.org * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 ***************************************************************************/ 0010 0011 #include "ec555.h" 0012 0013 #include "ecnode.h" 0014 #include "libraryitem.h" 0015 #include "pin.h" 0016 #include "resistance.h" 0017 0018 #include <KLocalizedString> 0019 #include <QPainter> 0020 0021 Item *EC555::construct(ItemDocument *itemDocument, bool newItem, const char *id) 0022 { 0023 return new EC555(static_cast<ICNDocument *>(itemDocument), newItem, id); 0024 } 0025 0026 LibraryItem *EC555::libraryItem() 0027 { 0028 return new LibraryItem(QStringList(QString("ec/555")), i18n("555"), i18n("Integrated Circuits"), "ic1.png", LibraryItem::lit_component, EC555::construct); 0029 } 0030 0031 EC555::EC555(ICNDocument *icnDocument, bool newItem, const char *id) 0032 : Component(icnDocument, newItem, (id) ? id : "555") 0033 { 0034 m_name = i18n("555"); 0035 // m_pins = QStringList::split( ',', "Gnd,Trg,Out,Res,CV,Th,Dis,Vcc" ); 0036 // m_pins = QStringList::split( ',', "Dis,Th,Trg,Gnd,CV,Out,Res,Vcc" ); 0037 0038 old_com1 = false; 0039 old_com2 = false; 0040 old_q = false; 0041 0042 setSize(-32, -32, 64, 64); 0043 0044 // Pins down left 0045 0046 // Pin 7 0047 discharge = createPin(-40, -16, 0, "Dis")->pin(); 0048 addDisplayText("dis", QRect(-32, -24, 24, 16), "Dis"); 0049 0050 // Pin 6 0051 threshold = createPin(-40, 0, 0, "Th")->pin(); 0052 addDisplayText("th", QRect(-32, -8, 24, 16), "Th"); 0053 0054 // Pin 2 0055 trigger = createPin(-40, 16, 0, "Trg")->pin(); 0056 addDisplayText("trg", QRect(-32, 8, 24, 16), "Trg"); 0057 0058 // Top two 0059 0060 // Pin 8 0061 vcc = createPin(-16, -40, 90, "Vcc")->pin(); 0062 addDisplayText("vcc", QRect(-24, -32, 16, 8), "+"); 0063 0064 // Pin 4 0065 reset = createPin(16, -40, 90, "Res")->pin(); 0066 addDisplayText("res", QRect(8, -28, 16, 16), "Res"); 0067 0068 // Bottom two 0069 0070 // Pin 1 0071 ground = createPin(-16, 40, 270, "Gnd")->pin(); 0072 addDisplayText("gnd", QRect(-24, 20, 16, 8), "-"); 0073 0074 // Pin 5 0075 control = createPin(16, 40, 270, "CV")->pin(); 0076 addDisplayText("cv", QRect(8, 12, 16, 16), "CV"); 0077 0078 // Output on right 0079 0080 // Pin 3 0081 output = createPin(40, 0, 180, "Out")->pin(); 0082 addDisplayText("out", QRect(8, -8, 16, 16), "Out"); 0083 0084 m_r1 = createResistance(vcc, control, 5e3); 0085 m_r23 = createResistance(control, ground, 1e4); 0086 m_po_sink = createResistance(output, ground, 0.); 0087 m_po_source = createResistance(output, vcc, 0.); 0088 m_po_source->setConductance(0.); 0089 m_r_discharge = createResistance(discharge, ground, 0.); 0090 } 0091 0092 EC555::~EC555() 0093 { 0094 } 0095 0096 // TODO: This is simulation code not UI code, so it shouldn't be here. 0097 // Would it be better to simulate the appropriate elements, ie comparator, voltage divider, 0098 // and flip-flop instead of all this hand-wavy logic? 0099 0100 void EC555::stepNonLogic() 0101 { 0102 double v_threshold = threshold->voltage(); 0103 double v_control = control->voltage(); 0104 double v_ground = ground->voltage(); 0105 double v_trigger = trigger->voltage(); 0106 double v_reset = reset->voltage(); 0107 double v_vcc = vcc->voltage(); 0108 double v_r = (v_control + v_ground) / 2; 0109 0110 bool com1 = (v_threshold == v_control) ? old_com1 : (v_threshold < v_control); 0111 bool com2 = (v_r == v_trigger) ? old_com2 : (v_r > v_trigger); 0112 bool reset = v_reset >= (v_control - v_ground) / 2 + v_ground; 0113 0114 old_com1 = com1; 0115 old_com2 = com2; 0116 0117 bool r = !(reset && com1); 0118 bool s = com2; 0119 bool q = old_q; 0120 0121 if (v_vcc - v_ground >= 2.5) { 0122 if (s && !r) { 0123 q = true; 0124 } else if (r && !s) { 0125 q = false; 0126 } 0127 } else { 0128 q = false; 0129 } 0130 0131 old_q = q; 0132 m_r_discharge->setConductance(0.); 0133 0134 if (q) { 0135 m_po_source->setResistance(10.); 0136 m_po_sink->setConductance(0.); 0137 } else { 0138 m_po_source->setConductance(0.); 0139 m_po_sink->setResistance(10.); 0140 0141 if (v_ground + 0.7 <= v_vcc) { 0142 m_r_discharge->setResistance(10.); 0143 } 0144 } 0145 }