Hello
I have another thread with regards to trying to get a working DMX routine on an ATmega328p... I have kinda solved that.
But, this code here (Yes, its a mess because it's work in progress) has this weird thing I cannot solve.
Near the end of the loop, if I use any kind of maths, bool statement etc, it freezes and will not allow the processor to run (it uploads via USBasp, but never runs).
As it is listed below, the routine works and reads DMX fine.
For instance...
I did have bools to monitor the state of the lights and servo being on/off, but stating servomotor = false would freeze the processor and I just could not work out why.
if ((RXDMXch1 > 128) and (servomotor ==false)) This froze the loop
So I changed that to be if ((RXDMXch1 > 128) and (digitalRead(pin1) == LOW)) and this worked.
But now the statement servopos = servostart stops it running? Eh? (currently commented out)
I think I am well within memory boundaries:
Sketch uses 16062 bytes (52%) of program storage space. Maximum is 30720 bytes.
Global variables use 885 bytes (43%) of dynamic memory, leaving 1163 bytes for local variables. Maximum is 2048 bytes.
So I can only assume I am somehow crashing into something in this horrible, troublesome DMX library?
#include <Wire.h> // I2C comms
#include <SPI.h> // Serial comms
#include <DMXSerial.h> // DMX library.
#include <Adafruit_GFX.h> // Graphics library
#include <Adafruit_SSD1306.h> // Oled screen (Adafruit SSD1306.H has list of commands)
#include <EEPROM.h> // EEPROM
#define DMXMODEPIN 17 // Define the DMX direction change pin (it's pin 2 default in the DMXSerial library)
#define DMX_USE_PORT0 // ATmega328p only has one serial port (0)
#define DMXSPEED 250000L // Already defined in the library
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Pin 0 = Serial RX Incoming DMX data
// Pin 1 = Serial TX Transmitted DMX data
#define pin1 2 // PCINT18
#define pin3 3 // PCINT19 - PWM
#define pin4 4 // PCINT20
#define pin5 5 // PCINT21 - PWM
#define pin6 6 // PCINT22 - PWM - AIN0
#define pin7 7 // PCINT23 - AIN1
#define pin8 8 // PCINT0
#define pin9 9 // PCINT1 - PWM
#define pin10 10 // PCINT2 - PWM - SS
// Pin 11 = Mosi // Used for programming but actually are available on the programming header
// Pin 12 = Miso // Used for programming but actually are available on the programming header
// Pin 13 = SCK // Used for programming but actually are available on the programming header
#define selectbutton 14 // // Onboard/remote SELECT button (PCINT8 - A0 - ADC0)
#define heartbeat 15 // Onboard LED indicator
#define pin2 16 // PCINT10 - A2 - ADC2
#define DMXdirection 17 // HIGH = Transmit. LOW = Receive
// Pin 18 SDA // I2C SDA to onboard OLED screen
// Pin 19 SCL // I2C SCL to onboard OLED screen
#define enterbutton A7 // Onboard/remote ENTER button
unsigned long currentMillis; // Timing variables
unsigned long heartbeatMillis;
bool ledstatus; // Flip/flop for status led
int entervalue; // Analogue value from the ENTER button pin
float servopulse = 0.1; // How fast the servo sweeps
bool servodir; // Flip/flop for servo direction
int servostart = 700; // Servo start angle
int servostop = 2300; // Servo stop angle
int servopos; // The value being sent to the servo
//int servopause = 500; // How long the servo pauses for
byte RXDMX1address = 1; // DMX variables
byte RXDMX2address = 2;
byte RXDMX3address = 3;
byte RXDMXch1 = 0;
byte RXDMXch2 = 0;
byte RXDMXch3 = 0;
byte oldRXDMXch1 = 0;
byte oldRXDMXch2 = 0;
byte oldRXDMXch3 = 0;
//----------------------------------------------------------------------------------------------------------------------------------------------------------------
void setup() {
pinMode (heartbeat, OUTPUT);
pinMode (DMXdirection, OUTPUT);
pinMode (enterbutton, INPUT);
pinMode (selectbutton, INPUT);
pinMode (pin1, OUTPUT);
pinMode (pin2, OUTPUT);
pinMode (pin3, INPUT);
pinMode (pin4, INPUT);
pinMode (pin5, INPUT);
pinMode (pin6, INPUT);
pinMode (pin7, INPUT);
pinMode (pin8, INPUT);
pinMode (pin9, INPUT);
pinMode (pin10, OUTPUT);
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3c);
DMXSerial.init(DMXReceiver); // DMX receiver
//DMXSerial.init(DMXController); // DMX transmitter
//DMXSerial.init(DMXProbe); //
digitalWrite(DMXdirection, LOW); // Enable receive
drawscreen();
drawheader();
delay(3000);
drawscreen();
drawRX();
}//------ end of setup---------
void drawscreen() {
display.clearDisplay(); // Clear the buffer.
display.drawRoundRect(0, 0, 128, 64, 4, WHITE); // Draws a rectangle with rounded corners. Starts at 0,0 (top left) and then 128 wide x 64 high with corners rounded to radius 4
display.drawRoundRect(2, 2, 124, 60, 4, WHITE);
}
void drawheader() {
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(18, 36);
display.print(F("DMX CONTROLLER"));
display.display();
}
void drawRX() { // Draw the DMX receive page
display.setTextSize(1);
display.drawRect(14, 6, 102, 12, WHITE);
display.setCursor(18, 8);
display.print(F("DMX RECEIVE MODE"));
display.fillRect(98, 23, 20, 37, BLACK);
display.setCursor(10, 24);
display.print(F("DMX 1 RX Value: "));
display.setCursor(100, 24);
display.print(RXDMXch1);
display.setCursor(10, 36);
display.print(F("DMX 2 RX Value: "));
display.setCursor(100, 36);
display.print(RXDMXch2);
display.setCursor(10, 48);
display.print(F("DMX 3 RX Value: "));
display.setCursor(100, 48);
display.print(RXDMXch3);
display.display();
}
//#####################################################################################################################
void loop() {
currentMillis = millis();
if (currentMillis - heartbeatMillis > 1000) { // Once a second heartbeat
if (ledstatus == false) {
ledstatus = true;
heartbeatMillis = currentMillis;
digitalWrite(heartbeat, HIGH);
}
else
{
ledstatus = false;
heartbeatMillis = currentMillis;
digitalWrite(heartbeat, LOW);
}
}
//--------------------------------------------- Buttons/Inputs ----------------------------------------------
entervalue = analogRead(enterbutton);
if (entervalue > 800) { // The ENTER button is analogue only
display.print(F("ENTER"));
display.display();
do {
entervalue = analogRead(enterbutton);
} while (entervalue > 800);
}
if (digitalRead(selectbutton) == HIGH) {
display.print(F("SELECT"));
display.display();
do {} while (digitalRead(selectbutton) == HIGH);
}
/*
if (digitalRead(pin1) == HIGH) {
display.print(F("1"));
display.display();
}
if (digitalRead(pin2) == HIGH) {
display.print(F("2"));
display.display();
}
if (digitalRead(pin3) == HIGH) {
display.print(F("3"));
display.display();
}
if (digitalRead(pin4) == HIGH) {
display.print(F("4"));
display.display();
}
if (digitalRead(pin5) == HIGH) {
display.print(F("5"));
display.display();
}
if (digitalRead(pin6) == HIGH) {
display.print(F("6"));
display.display();
}
if (digitalRead(pin7) == HIGH) {
display.print(F("7"));
display.display();
}
if (digitalRead(pin8) == HIGH) {
display.print(F("8"));
display.display();
}
if (digitalRead(pin9) == HIGH) {
display.print(F("9"));
display.display();
}
if (digitalRead(pin10) == HIGH) {
display.print(F("10"));
display.display();
}
*/
//------------------------------------------------------ DMX --------------------------------------------------------
unsigned long lastPacket = DMXSerial.noDataSince(); // Calculate how long no data packet was received
if (lastPacket < 6000) { // Read DMX value
RXDMXch1 = DMXSerial.read(RXDMX1address);
RXDMXch2 = DMXSerial.read(RXDMX2address);
RXDMXch3 = DMXSerial.read(RXDMX3address);
} else { // Display DMX Receive error
delay(200);
drawscreen();
display.setCursor(11, 23);
display.setTextSize(2);
display.print(F("DMX ERROR"));
display.display();
delay(1000);
drawscreen();
drawRX();
}
if ((RXDMXch1 != oldRXDMXch1) or (RXDMXch2 != oldRXDMXch2) or (RXDMXch3 != oldRXDMXch3)) { // Update the screen and any outputs
drawRX();
oldRXDMXch1 = RXDMXch1;
oldRXDMXch2 = RXDMXch2;
oldRXDMXch3 = RXDMXch3;
}
if ((RXDMXch1 > 128) and (digitalRead(pin1) == LOW)) { // Turn on the light
digitalWrite(pin1, HIGH);
}
if ((RXDMXch1 <= 128) and (digitalRead(pin1) == HIGH)) {
digitalWrite(pin1, LOW);
}
if ((RXDMXch2 > 128) and (digitalRead(pin2) == LOW)) { // Turn on the servo power
digitalWrite(pin2, HIGH);
}
if ((RXDMXch2 <= 128) and (digitalRead(pin2) == HIGH)) {
digitalWrite(pin2, LOW);
}
// Introduce a millis delay here to create a pause
if ((RXDMXch3 > 0) and (digitalRead(pin1) == HIGH)) {
if (servopos < (servostart + 1)) { // Limit the start position and flip the direction
servodir = true;
//servopos = servostart; // ###################### WTF #################
}
if (servopos > servostop) { // Limit the stop position and flip the direction
servodir = false;
//servopos = servostop;
}
}
/*
servopulse = RXDMXch3 / 10; // Slow up the 0-255 variable
if (servodir == true) { // Sweep up
servopos = servopos + servopulse;
// Graphics here
}
if (servodir == false) { // Sweep back
servopos = servopos - servopulse;
// Graphics here
}
*/
}
//#####################################################################################################################
