Jump to content

Middlefart

Members
  • Posts

    79
  • Joined

  • Last visited

Everything posted by Middlefart

  1. Yes. Have a look at the EngineCluster sketches at my github https://github.com/Middlefart/DCS-A10/tree/master/Sketches It uses the SwitecX12 library, also on my github Skickat från min iPhone med Tapatalk
  2. I use double sided tape. Works like a charm
  3. Actually I use Jlcpcb when ordering Pcb’s:-) However, I’ve also started milling pcb’s myself. Good for testing and small batches.
  4. Here is a working sketch. There where some copy/paste errors in the previous version and some other stuff that also was wrong. Apparently I had lost the old working version but I managed to get it working again. //Uncomment for testmode (No DCS needed) //#define TEST #ifndef TEST #define DCSBIOS_IRQ_SERIAL //#define DCSBIOS_RS485_SLAVE 2 #include "DcsBios.h" #endif #define TXENABLE_PIN 2 #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include "characters.h" #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 // OLED display height, in pixels #define TCAAddress 0x70 #define AltAddress 0 #define HGAddress 1 // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin) int updateInterval = 100; //the number of milliseconds between updates struct scrollDigit { int digit; int y; }; struct disp { Adafruit_SSD1306 display; int address; int width; int numberOfDigits; scrollDigit digits[5]; }; disp displays[2] = { {Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET), AltAddress, 24, 5, {{0,0},{0,0},{0,0},{0,0},{0,0}}}, {Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET), HGAddress, 16, 4, {{0,0},{0,0},{0,0},{0,0},{0,0}}} }; void TCASelect(uint8_t addr) { if (addr > 7) return; Wire.beginTransmission(TCAAddress); Wire.write(1 << addr); Wire.endTransmission(); } void setup() { for (int i = 0; i<2; i++) { TCASelect(displays[i].address); if(!displays[i].display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32 for(;;); // Don't proceed, loop forever } } #ifdef TEST Serial.begin(9600); #else DcsBios::setup(); #endif UpdateDisplays(); } void UpdateDisplays() { for (int j = 0; j<2; j++) { TCASelect(displays[j].address); displays[j].display.clearDisplay(); for (int i = 0; i < displays[j].numberOfDigits; i++) { printScrollingDigit(displays[j].digits[i].digit, displays[j].width, displays[j].digits[i].y, i + 1, &displays[j]); } if (displays[j].width == 16) { displays[j].display.fillRect(0, 25, 128, 7, BLACK); } displays[j].display.display(); } } void printScrollingDigit(int digit, int width, int y, int pos, disp *display) { // int width = 24; int x = (width * pos) - width + pos; if (width == 24) { switch (digit) { case -1: display->display.drawBitmap(x, y, c24_Empty, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_1, 24, 32, 1); break; case 1: display->display.drawBitmap(x, y, c24_1, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_2, 24, 32, 1); break; case 2: display->display.drawBitmap(x, y, c24_2, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_3, 24, 32, 1); break; case 3: display->display.drawBitmap(x, y, c24_3, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_4, 24, 32, 1); break; case 4: display->display.drawBitmap(x, y, c24_4, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_5, 24, 32, 1); break; case 5: display->display.drawBitmap(x, y, c24_5, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_6, 24, 32, 1); break; case 6: display->display.drawBitmap(x, y, c24_6, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_7, 24, 32, 1); break; case 7: display->display.drawBitmap(x, y, c24_7, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_8, 24, 32, 1); break; case 8: display->display.drawBitmap(x, y, c24_8, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_9, 24, 32, 1); break; case 9: display->display.drawBitmap(x, y, c24_9, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_0, 24, 32, 1); break; default: display->display.drawBitmap(x, y, c24_0, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_1, 24, 32, 1); break; } } else { switch (digit) { case -1: display->display.drawBitmap(x, y, c16_Empty, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_1, 16, 24, 1); break; case 1: display->display.drawBitmap(x, y, c16_1, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_2, 16, 24, 1); break; case 2: display->display.drawBitmap(x, y, c16_2, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_3, 16, 24, 1); break; case 3: display->display.drawBitmap(x, y, c16_3, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_4, 16, 24, 1); break; case 4: display->display.drawBitmap(x, y, c16_4, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_5, 16, 24, 1); break; case 5: display->display.drawBitmap(x, y, c16_5, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_6, 16, 24, 1); break; case 6: display->display.drawBitmap(x, y, c16_6, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_7, 16, 24, 1); break; case 7: display->display.drawBitmap(x, y, c16_7, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_8, 16, 24, 1); break; case 8: display->display.drawBitmap(x, y, c16_8, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_9, 16, 24, 1); break; case 9: display->display.drawBitmap(x, y, c16_9, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_0, 16, 24, 1); break; default: display->display.drawBitmap(x, y, c16_0, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_1, 16, 24, 1); break; } } } void onAlt10000FtChange(unsigned int newValue) { unsigned int mappedValue = newValue / 6553; unsigned int y = map(newValue, mappedValue * 6553, mappedValue * 6553 + 6553, 0, -33); if (mappedValue == 0) { mappedValue = -1; } displays[AltAddress].digits[0].digit = mappedValue; displays[AltAddress].digits[0].y = y; } void onAlt1000FtChange(unsigned int newValue) { unsigned int mappedValue = newValue / 6553; unsigned int y = map(newValue, mappedValue * 6553, mappedValue * 6553 + 6553, 0, -33); displays[AltAddress].digits[1].digit = mappedValue; displays[AltAddress].digits[1].y = y; } void onAlt100FtChange(unsigned int newValue) { unsigned int mappedValue = newValue / 6553; unsigned int y = map(newValue, mappedValue * 6553, mappedValue * 6553 + 6553, 0, -33); displays[AltAddress].digits[2].digit = mappedValue; displays[AltAddress].digits[2].y = y; } void onBaro0Change(unsigned int newValue) { unsigned int mappedValue = newValue / 6554; unsigned int y = map(newValue, mappedValue * 6554, mappedValue * 6554 + 6554, 0, -25); displays[HGAddress].digits[3].digit = mappedValue; displays[HGAddress].digits[3].y = y; } void onBaro1Change(unsigned int newValue) { unsigned int mappedValue = newValue / 6554; unsigned int y = map(newValue, mappedValue * 6554, mappedValue * 6554 + 6554, 0, -25); displays[HGAddress].digits[2].digit = mappedValue; displays[HGAddress].digits[2].y = y; } void onBaro2Change(unsigned int newValue) { unsigned int mappedValue = newValue / 6554; unsigned int y = map(newValue, mappedValue * 6554, mappedValue * 6554 + 6554, 0, -25); displays[HGAddress].digits[1].digit = mappedValue; displays[HGAddress].digits[1].y = y; } void onBaro3Change(unsigned int newValue) { unsigned int mappedValue = newValue / 6554; unsigned int y = map(newValue, mappedValue * 6554, mappedValue * 6554 + 6554, 0, -25); displays[HGAddress].digits[0].digit = mappedValue; displays[HGAddress].digits[0].y = y; } #ifndef TEST DcsBios::IntegerBuffer Alt10000FtBuffer(0x1080, 0xffff, 0, onAlt10000FtChange); DcsBios::IntegerBuffer Alt1000FtBuffer(0x1082, 0xffff, 0, onAlt1000FtChange); DcsBios::IntegerBuffer Alt100FtBuffer(0x1084, 0xffff, 0, onAlt100FtChange); DcsBios::IntegerBuffer Baro0Buffer(0x1086, 0xffff, 0, onBaro0Change); DcsBios::IntegerBuffer Baro1Buffer(0x1088, 0xffff, 0, onBaro1Change); DcsBios::IntegerBuffer Baro2Buffer(0x108a, 0xffff, 0, onBaro2Change); DcsBios::IntegerBuffer Baro3Buffer(0x108c, 0xffff, 0, onBaro3Change); #endif unsigned long time = 0; unsigned int i = 0; void loop() { #ifndef TEST DcsBios::loop(); #endif time = millis(); if (time % updateInterval == 0) { #ifdef TEST onAlt10000FtChange(i); onAlt1000FtChange(i); onAlt100FtChange(i); onBaro0Change(i); onBaro1Change(i); onBaro2Change(i); onBaro3Change(i); i += 400; #endif UpdateDisplays(); } } I tested it in DCS and everything works as it should.
  5. Sorry about that. I was pretty sure that this was the sketch I used, but I realise that it can't be. I'll dig around and try to find the working version
  6. Disclaimer: I'm not sure that the sketch in the previous post is 100% working but I think so :-)
  7. You might wanna have a look at this sketch. This is my original one which i used in conjunction with a I2C Multiplexer to drive two displays (with the same address) from the same Arduino Nano. You need to do some changes since you are not using the Multiplexer but the base functionality should be the same. #define DCSBIOS_RS485_SLAVE 2 #define TXENABLE_PIN 2 #include "DcsBios.h" #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include "characters.h" #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 // OLED display height, in pixels #define TCAAddress 0x70 #define AltAddress 0 #define HGAddress 1 // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins) #define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin) struct scrollDigit { int digit; int y; }; struct disp { Adafruit_SSD1306 display; int address; int width; int numberOfDigits; scrollDigit digits[5]; }; disp displays[2] = { {Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET), 0, 24, 5, {{0,0},{0,0},{0,0},{0,0},{0,0}}}, {Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET), 1, 16, 4, {{0,0},{0,0},{0,0},{0,0},{0,0}}} }; void TCASelect(uint8_t addr) { if (addr > 7) return; Wire.beginTransmission(TCAAddress); Wire.write(1 << addr); Wire.endTransmission(); } void setup() { for (int i = 0; i<2; i++) { TCASelect(displays[i].address); if(!displays[i].display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32 for(;;); // Don't proceed, loop forever } } DcsBios::setup(); } void UpdateDisplays() { for (int j = 0; j<2; j++) { TCASelect(displays[j].address); displays[j].display.clearDisplay(); for (int i = 0; i < displays[j].numberOfDigits; i++) { printScrollingDigit(displays[j].digits[i].digit, displays[j].width, displays[j].digits[i].y, i + 1, &displays[j]); } if (displays[j].width == 16) { displays[j].display.fillRect(0, 25, 128, 7, BLACK); } displays[j].display.display(); } } void printScrollingDigit(int digit, int width, int y, int pos, disp *display) { // int width = 24; int x = (width * pos) - width + pos; if (width == 24) { switch (digit) { case -1: display->display.drawBitmap(x, y, c24_Empty, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_1, 24, 32, 1); break; case 1: display->display.drawBitmap(x, y, c24_1, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_2, 24, 32, 1); break; case 2: display->display.drawBitmap(x, y, c24_2, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_3, 24, 32, 1); break; case 3: display->display.drawBitmap(x, y, c24_3, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_4, 24, 32, 1); break; case 4: display->display.drawBitmap(x, y, c24_4, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_5, 24, 32, 1); break; case 5: display->display.drawBitmap(x, y, c24_5, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_6, 24, 32, 1); break; case 6: display->display.drawBitmap(x, y, c24_6, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_7, 24, 32, 1); break; case 7: display->display.drawBitmap(x, y, c24_7, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_8, 24, 32, 1); break; case 8: display->display.drawBitmap(x, y, c24_8, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_9, 24, 32, 1); break; case 9: display->display.drawBitmap(x, y, c24_9, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_0, 24, 32, 1); break; default: display->display.drawBitmap(x, y, c24_0, 24, 32, 1); display->display.drawBitmap(x, y+33, c24_1, 24, 32, 1); break; } } else { switch (digit) { case -1: display->display.drawBitmap(x, y, c16_Empty, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_1, 16, 24, 1); break; case 1: display->display.drawBitmap(x, y, c16_1, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_2, 16, 24, 1); break; case 2: display->display.drawBitmap(x, y, c16_2, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_3, 16, 24, 1); break; case 3: display->display.drawBitmap(x, y, c16_3, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_4, 16, 24, 1); break; case 4: display->display.drawBitmap(x, y, c16_4, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_5, 16, 24, 1); break; case 5: display->display.drawBitmap(x, y, c16_5, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_6, 16, 24, 1); break; case 6: display->display.drawBitmap(x, y, c16_6, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_7, 16, 24, 1); break; case 7: display->display.drawBitmap(x, y, c16_7, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_8, 16, 24, 1); break; case 8: display->display.drawBitmap(x, y, c16_8, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_9, 16, 24, 1); break; case 9: display->display.drawBitmap(x, y, c16_9, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_0, 16, 24, 1); break; default: display->display.drawBitmap(x, y, c16_0, 16, 24, 1); display->display.drawBitmap(x, y+25, c16_1, 16, 24, 1); break; } } } void onAlt10000FtChange(unsigned int newValue) { void onAlt10000FtChange(unsigned int newValue) { unsigned int mappedValue = newValue / 6553; unsigned int y = map(newValue, mappedValue * 6553, mappedValue * 6553 + 6553, 0, YPos()); if (mappedValue == 0) { mappedValue = -1; } oled.digits[0].digit = mappedValue; oled.digits[0].y = y; } } void onAlt1000FtChange(unsigned int newValue) { unsigned int mappedValue = newValue / 6553; unsigned int y = map(newValue, mappedValue * 6553, mappedValue * 6553 + 6553, 0, -33); displays[AltAddress].digits[1].digit = mappedValue; displays[AltAddress].digits[1].y = y; // UpdateDisplays(); } void onAlt100FtChange(unsigned int newValue) { unsigned int mappedValue = newValue / 6553; unsigned int y = map(newValue, mappedValue * 6553, mappedValue * 6553 + 6553, 0, -33); displays[AltAddress].digits[2].digit = mappedValue; displays[AltAddress].digits[2].y = y; //UpdateDisplays(); } void onBaro0Change(unsigned int newValue) { unsigned int mappedValue = newValue / 6554; unsigned int y = map(newValue, mappedValue * 6554, mappedValue * 6554 + 6554, 0, -25); displays[HGAddress].digits[3].digit = mappedValue; displays[HGAddress].digits[3].y = y; //UpdateDisplays(); } void onBaro1Change(unsigned int newValue) { unsigned int mappedValue = newValue / 6554; unsigned int y = map(newValue, mappedValue * 6554, mappedValue * 6554 + 6554, 0, -25); displays[HGAddress].digits[2].digit = mappedValue; displays[HGAddress].digits[2].y = y; // UpdateDisplays(); } void onBaro2Change(unsigned int newValue) { unsigned int mappedValue = newValue / 6554; unsigned int y = map(newValue, mappedValue * 6554, mappedValue * 6554 + 6554, 0, -25); displays[HGAddress].digits[1].digit = mappedValue; displays[HGAddress].digits[1].y = y; // UpdateDisplays(); } void onBaro3Change(unsigned int newValue) { unsigned int mappedValue = newValue / 6554; unsigned int y = map(newValue, mappedValue * 6554, mappedValue * 6554 + 6554, 0, -25); displays[HGAddress].digits[0].digit = mappedValue; displays[HGAddress].digits[0].y = y; // UpdateDisplays(); } DcsBios::IntegerBuffer Alt10000FtBuffer(0x1080, 0xffff, 0, onAlt10000FtChange); DcsBios::IntegerBuffer Alt1000FtBuffer(0x1082, 0xffff, 0, onAlt1000FtChange); DcsBios::IntegerBuffer Alt100FtBuffer(0x1084, 0xffff, 0, onAlt100FtChange); DcsBios::IntegerBuffer Baro0Buffer(0x1086, 0xffff, 0, onBaro0Change); DcsBios::IntegerBuffer Baro1Buffer(0x1088, 0xffff, 0, onBaro1Change); DcsBios::IntegerBuffer Baro2Buffer(0x108a, 0xffff, 0, onBaro2Change); DcsBios::IntegerBuffer Baro3Buffer(0x108c, 0xffff, 0, onBaro3Change); int count = 0; void loop() { DcsBios::loop(); count++; if (count % 100 == 0) { UpdateDisplays(); } }
  8. :thumbup: Yes I agree. I would like a more beefed up version of the nano with a little more oumph! Would be nice to have a little more CPU to play with
  9. I make my panels from acrylic which I laser cut on a K40 laser. Engaved panels are made from white acrylic which i paint black and then laser engave the paint away where the text etc is. Some parts are 3D-printed on a Creality Ender 3. PCB's I either etch myself or order från JLCPCB.
  10. The latest version of the sketch can now be found on https://github.com/Middlefart/DCS-A10
  11. Good to hear! :thumbup: The latest version of the sketch can now be found on https://github.com/Middlefart/DCS-A10
  12. Jittery output for Altimeter data I have tested the dropbox version for 20 minutes now without any problems
  13. I'm pretty confident that the bug has been resolved. A new sketch is available on https://www.dropbox.com/sh/uaozt4p6z...YdFYZRcKa?dl=0
  14. No glitches/jitters since I changed this. DCS has been running for 15 minutes. I really think this solved it. If that's the case I was right. Bad data, not bad code :D Well. Not very bad code at least :music_whistling: I've uploaded my latest sketch to https://www.dropbox.com/sh/uaozt4p6z1yx0wd/AAAMB3i172vHYOTcYdFYZRcKa?dl=0 Feel free to use it I'm gonna try to set up a GitHub repository for this and other sketches I've created.
  15. I think I found it. Change #define DCSBIOS_DEFAULT_SERIAL to #define DCSBIOS_IRQ_SERIAL In the example sketch for DCSBIOS_DEFAULT_SERIAL there is a comment. /* Tell DCS-BIOS to use a serial connection and use the default Arduino Serial library. This will work on the vast majority of Arduino-compatible boards, [b]but you can get corrupted data[/b] if you have too many or too slow outputs (e.g. when you have multiple character displays), because the receive buffer can fill up if the sketch spends too much time updating them. If you can, use the IRQ Serial connection instead. */ I think this is the problem. I tested using #define DCSBIOS_IRQ_SERIAL and didn't get a glitch on a 5 minute test flight. When i developed this I used an rs485 network and maybe that is the reason to why I didn't get any problems then. When people asked for the sketch i threw together this sketch and changed to DCSBIOS_DEFAULT_SERIAL from RS485 Could you please test it?
  16. Yeah. I start to realize that the data is correct. I'll keep digging :-)
  17. It just struck me. I’ve seen this kind of behavior before in another sketch and without any oleds or I2C. When I was testing a stepper motor for the altimeter everything was working as it should except for once in a while where the motor all of a sudden would jerk and move the needle to completely the wrong position and then move back again to the correct position. That could be caused of an invalid value from DCS bios (or DCS). Im not sure if I got to the bottom of it or if it’s still a problem. That was just on a test board which has been torn apart so I can’t check it. I’ll try to find the sketch however, I should have that somewhere. I’ll also try to do some logging of the raw data that the arduino gets and check if all looks good there.
  18. hmmm. I tested without the fancy font/bitmaps and without scrolling/rolling (just printing the mapped value using println) and still got the jitters. I don't think its a problem with the OLED not keeping up with the data being pushed to it, rather something funny going on with the data itself, either the mapped values goes totally bonkers or DCS Bios sends strange values. My bet is on my code :-) I'll keep testing
  19. I answered in the other thread. https://forums.eagle.ru/showpost.php?p=4342258&postcount=38
  20. Really strange. I just tested it and immediately got the same problem... I never got this while I was developing the code. I'll have a look in to it as well
  21. I just found this thread. That looks really strange. My displays never behaved like that. I have however not tested it that much since I had to put my sim on ice for a while. Please let me know if you find the problem.
  22. I am aware of the problem and corrected it last weekend but forgot to post it here :-) My new version of the code looks like this: void onAlt10000FtChange(unsigned int newValue) { unsigned int mappedValue = newValue / 6553; unsigned int y = map(newValue, mappedValue * 6553, mappedValue * 6553 + 6553, 0, YPos()); if (mappedValue == 0) { mappedValue = -1; } oled.digits[0].digit = mappedValue; oled.digits[0].y = y; }
  23. I found it 30 seconds after my original post. the correct syntax is {down = 3006, up = 3006, cockpit_device_id = 36, value_down = 1.0, value_up = 0.0, name = _('Right wing tank boost pump'), category = _('Fuel system control panel')},
  24. I'm trying to change the Right Wing Boost pump to a two way switch (So that I can use it in my cockpit) by changing default.lua for the A-10C. However something is wrong with my changes below. After this change the Control tab in the options menu is blank in DCS, indicating that something is wrong, but I can't figure out what i did wrong. Can someone spot the error? {down = device_commands.Button_6, up = device_commands.Button_6, cockpit_device_id = devices.FUEL_SYSTEM, value_down = 1.0, value_up = 0.0, name = _('Right wing tank boost pump'), category = _('Fuel system control panel')},
×
×
  • Create New...