DEV Community

jay jordan
jay jordan

Posted on

portable television 3d printer

define X_STEP_PIN 54

define X_DIR_PIN 55

define X_ENABLE_PIN 38

define X_MIN_PIN 3

define X_MAX_PIN 2

define Y_STEP_PIN 60

define Y_DIR_PIN 61

define Y_ENABLE_PIN 56

define Y_MIN_PIN 14

define Y_MAX_PIN 15

define Z_STEP_PIN 46

define Z_DIR_PIN 48

define Z_ENABLE_PIN 62

define Z_MIN_PIN 18

define Z_MAX_PIN 19

define E_STEP_PIN 26

define E_DIR_PIN 28

define E_ENABLE_PIN 24

define Q_STEP_PIN 36

define Q_DIR_PIN 34

define Q_ENABLE_PIN 30

define SDPOWER -1

define SDSS 53

define LED_PIN 13

define FAN_PIN 9

define PS_ON_PIN 12

define KILL_PIN -1

define HEATER_0_PIN 10

define HEATER_1_PIN 8

define TEMP_0_PIN 13 // ANALOG NUMBERING

define TEMP_1_PIN 14 // ANALOG NUMBERING

void setup() {

pinMode(FAN_PIN , OUTPUT);

pinMode(HEATER_0_PIN , OUTPUT);

pinMode(HEATER_1_PIN , OUTPUT);

pinMode(LED_PIN , OUTPUT);

pinMode(X_STEP_PIN , OUTPUT);

pinMode(X_DIR_PIN , OUTPUT);

pinMode(X_ENABLE_PIN , OUTPUT);

pinMode(Y_STEP_PIN , OUTPUT);

pinMode(Y_DIR_PIN , OUTPUT);

pinMode(Y_ENABLE_PIN , OUTPUT);

pinMode(Z_STEP_PIN , OUTPUT);

pinMode(Z_DIR_PIN , OUTPUT);

pinMode(Z_ENABLE_PIN , OUTPUT);

pinMode(E_STEP_PIN , OUTPUT);

pinMode(E_DIR_PIN , OUTPUT);

pinMode(E_ENABLE_PIN , OUTPUT);

pinMode(Q_STEP_PIN , OUTPUT);

pinMode(Q_DIR_PIN , OUTPUT);

pinMode(Q_ENABLE_PIN , OUTPUT);

digitalWrite(X_ENABLE_PIN , LOW);

digitalWrite(Y_ENABLE_PIN , LOW);

digitalWrite(Z_ENABLE_PIN , LOW);

digitalWrite(E_ENABLE_PIN , LOW);

digitalWrite(Q_ENABLE_PIN , LOW);

}

void loop () {

if (millis() %1000 <500)

digitalWrite(LED_PIN, HIGH);

else

digitalWrite(LED_PIN, LOW);

if (millis() %1000 <300) {

digitalWrite(HEATER_0_PIN, HIGH);

digitalWrite(HEATER_1_PIN, LOW);

digitalWrite(FAN_PIN, LOW);

} else if (millis() %1000 <600) {

digitalWrite(HEATER_0_PIN, LOW);

digitalWrite(HEATER_1_PIN, HIGH);

digitalWrite(FAN_PIN, LOW);

} else {

digitalWrite(HEATER_0_PIN, LOW);

digitalWrite(HEATER_1_PIN, LOW);

digitalWrite(FAN_PIN, HIGH);

}

if (millis() %10000 <5000) {

digitalWrite(X_DIR_PIN , HIGH);

digitalWrite(Y_DIR_PIN , HIGH);

digitalWrite(Z_DIR_PIN , HIGH);

digitalWrite(E_DIR_PIN , HIGH);

digitalWrite(Q_DIR_PIN , HIGH);

}

else {

digitalWrite(X_DIR_PIN , LOW);

digitalWrite(Y_DIR_PIN , LOW);

digitalWrite(Z_DIR_PIN , LOW);

digitalWrite(E_DIR_PIN , LOW);

digitalWrite(Q_DIR_PIN , LOW);

}

digitalWrite(X_STEP_PIN , HIGH);

digitalWrite(Y_STEP_PIN , HIGH);

digitalWrite(Z_STEP_PIN , HIGH);

digitalWrite(E_STEP_PIN , HIGH);

digitalWrite(Q_STEP_PIN , HIGH);

delay(1);

digitalWrite(X_STEP_PIN , LOW);

digitalWrite(Y_STEP_PIN , LOW);

digitalWrite(Z_STEP_PIN , LOW);

digitalWrite(E_STEP_PIN , LOW);

digitalWrite(Q_STEP_PIN , LOW);

}

This code should activate all the steppers, fans, and heaters. The only problem with this code is that it does not activate both z-axis steppers; it only activates one. If you encounter any problems with any of the components, try isolating them and only running them in the code. If you would like to test the z-axis and thermistor, download the following codes:

ifndef THERMISTORTABLES_H_

define THERMISTORTABLES_H_

define OVERSAMPLENR 16

if (THERMISTORHEATER_0 == 1) || (THERMISTORHEATER_1 == 1) || (THERMISTORHEATER_2 == 1) || (THERMISTORBED == 1) //100k bed thermistor

const short temptable_1[][2] PROGMEM = {
{ 23*OVERSAMPLENR , 300 },
{ 25*OVERSAMPLENR , 295 },
{ 27*OVERSAMPLENR , 290 },
{ 28*OVERSAMPLENR , 285 },
{ 31*OVERSAMPLENR , 280 },
{ 33*OVERSAMPLENR , 275 },
{ 35*OVERSAMPLENR , 270 },
{ 38*OVERSAMPLENR , 265 },
{ 41*OVERSAMPLENR , 260 },
{ 44*OVERSAMPLENR , 255 },
{ 48*OVERSAMPLENR , 250 },
{ 52*OVERSAMPLENR , 245 },
{ 56*OVERSAMPLENR , 240 },
{ 61*OVERSAMPLENR , 235 },
{ 66*OVERSAMPLENR , 230 },
{ 71*OVERSAMPLENR , 225 },
{ 78*OVERSAMPLENR , 220 },
{ 84*OVERSAMPLENR , 215 },
{ 92*OVERSAMPLENR , 210 },
{ 100*OVERSAMPLENR , 205 },
{ 109*OVERSAMPLENR , 200 },
{ 120*OVERSAMPLENR , 195 },
{ 131*OVERSAMPLENR , 190 },
{ 143*OVERSAMPLENR , 185 },
{ 156*OVERSAMPLENR , 180 },
{ 171*OVERSAMPLENR , 175 },
{ 187*OVERSAMPLENR , 170 },
{ 205*OVERSAMPLENR , 165 },
{ 224*OVERSAMPLENR , 160 },
{ 245*OVERSAMPLENR , 155 },
{ 268*OVERSAMPLENR , 150 },
{ 293*OVERSAMPLENR , 145 },
{ 320*OVERSAMPLENR , 140 },
{ 348*OVERSAMPLENR , 135 },
{ 379*OVERSAMPLENR , 130 },
{ 411*OVERSAMPLENR , 125 },
{ 445*OVERSAMPLENR , 120 },
{ 480*OVERSAMPLENR , 115 },
{ 516*OVERSAMPLENR , 110 },
{ 553*OVERSAMPLENR , 105 },
{ 591*OVERSAMPLENR , 100 },
{ 628*OVERSAMPLENR , 95 },
{ 665*OVERSAMPLENR , 90 },
{ 702*OVERSAMPLENR , 85 },
{ 737*OVERSAMPLENR , 80 },
{ 770*OVERSAMPLENR , 75 },
{ 801*OVERSAMPLENR , 70 },
{ 830*OVERSAMPLENR , 65 },
{ 857*OVERSAMPLENR , 60 },
{ 881*OVERSAMPLENR , 55 },
{ 903*OVERSAMPLENR , 50 },
{ 922*OVERSAMPLENR , 45 },
{ 939*OVERSAMPLENR , 40 },
{ 954*OVERSAMPLENR , 35 },
{ 966*OVERSAMPLENR , 30 },
{ 977*OVERSAMPLENR , 25 },
{ 985*OVERSAMPLENR , 20 },
{ 993*OVERSAMPLENR , 15 },
{ 999*OVERSAMPLENR , 10 },
{ 1004*OVERSAMPLENR , 5 },
{ 1008*OVERSAMPLENR , 0 } //safety
};

endif

if (THERMISTORHEATER_0 == 2) || (THERMISTORHEATER_1 == 2) || (THERMISTORHEATER_2 == 2) || (THERMISTORBED == 2) //200k bed thermistor

const short temptable_2[][2] PROGMEM = {
{1*OVERSAMPLENR, 848},
{54*OVERSAMPLENR, 275},
{107*OVERSAMPLENR, 228},
{160*OVERSAMPLENR, 202},
{213*OVERSAMPLENR, 185},
{266*OVERSAMPLENR, 171},
{319*OVERSAMPLENR, 160},
{372*OVERSAMPLENR, 150},
{425*OVERSAMPLENR, 141},
{478*OVERSAMPLENR, 133},
{531*OVERSAMPLENR, 125},
{584*OVERSAMPLENR, 118},
{637*OVERSAMPLENR, 110},
{690*OVERSAMPLENR, 103},
{743*OVERSAMPLENR, 95},
{796*OVERSAMPLENR, 86},
{849*OVERSAMPLENR, 77},
{902*OVERSAMPLENR, 65},
{955*OVERSAMPLENR, 49},
{1008*OVERSAMPLENR, 17},
{1020*OVERSAMPLENR, 0} //safety
};

endif

if (THERMISTORHEATER_0 == 3) || (THERMISTORHEATER_1 == 3) || (THERMISTORHEATER_2 == 3) || (THERMISTORBED == 3) //mendel-parts

const short temptable_3[][2] PROGMEM = {
{1*OVERSAMPLENR,864},
{21*OVERSAMPLENR,300},
{25*OVERSAMPLENR,290},
{29*OVERSAMPLENR,280},
{33*OVERSAMPLENR,270},
{39*OVERSAMPLENR,260},
{46*OVERSAMPLENR,250},
{54*OVERSAMPLENR,240},
{64*OVERSAMPLENR,230},
{75*OVERSAMPLENR,220},
{90*OVERSAMPLENR,210},
{107*OVERSAMPLENR,200},
{128*OVERSAMPLENR,190},
{154*OVERSAMPLENR,180},
{184*OVERSAMPLENR,170},
{221*OVERSAMPLENR,160},
{265*OVERSAMPLENR,150},
{316*OVERSAMPLENR,140},
{375*OVERSAMPLENR,130},
{441*OVERSAMPLENR,120},
{513*OVERSAMPLENR,110},
{588*OVERSAMPLENR,100},
{734*OVERSAMPLENR,80},
{856*OVERSAMPLENR,60},
{938*OVERSAMPLENR,40},
{986*OVERSAMPLENR,20},
{1008*OVERSAMPLENR,0},
{1018*OVERSAMPLENR,-20}
};

endif

if (THERMISTORHEATER_0 == 4) || (THERMISTORHEATER_1 == 4) || (THERMISTORHEATER_2 == 4) || (THERMISTORBED == 4) //10k thermistor

const short temptable_4[][2] PROGMEM = {
{1*OVERSAMPLENR, 430},
{54*OVERSAMPLENR, 137},
{107*OVERSAMPLENR, 107},
{160*OVERSAMPLENR, 91},
{213*OVERSAMPLENR, 80},
{266*OVERSAMPLENR, 71},
{319*OVERSAMPLENR, 64},
{372*OVERSAMPLENR, 57},
{425*OVERSAMPLENR, 51},
{478*OVERSAMPLENR, 46},
{531*OVERSAMPLENR, 41},
{584*OVERSAMPLENR, 35},
{637*OVERSAMPLENR, 30},
{690*OVERSAMPLENR, 25},
{743*OVERSAMPLENR, 20},
{796*OVERSAMPLENR, 14},
{849*OVERSAMPLENR, 7},
{902*OVERSAMPLENR, 0},
{955*OVERSAMPLENR, -11},
{1008*OVERSAMPLENR, -35}
};

endif

if (THERMISTORHEATER_0 == 5) || (THERMISTORHEATER_1 == 5) || (THERMISTORHEATER_2 == 5) || (THERMISTORBED == 5) //100k ParCan thermistor (104GT-2)

const short temptable_5[][2] PROGMEM = {
{1*OVERSAMPLENR, 713},
{18*OVERSAMPLENR, 316},
{35*OVERSAMPLENR, 266},
{52*OVERSAMPLENR, 239},
{69*OVERSAMPLENR, 221},
{86*OVERSAMPLENR, 208},
{103*OVERSAMPLENR, 197},
{120*OVERSAMPLENR, 188},
{137*OVERSAMPLENR, 181},
{154*OVERSAMPLENR, 174},
{171*OVERSAMPLENR, 169},
{188*OVERSAMPLENR, 163},
{205*OVERSAMPLENR, 159},
{222*OVERSAMPLENR, 154},
{239*OVERSAMPLENR, 150},
{256*OVERSAMPLENR, 147},
{273*OVERSAMPLENR, 143},
{290*OVERSAMPLENR, 140},
{307*OVERSAMPLENR, 136},
{324*OVERSAMPLENR, 133},
{341*OVERSAMPLENR, 130},
{358*OVERSAMPLENR, 128},
{375*OVERSAMPLENR, 125},
{392*OVERSAMPLENR, 122},
{409*OVERSAMPLENR, 120},
{426*OVERSAMPLENR, 117},
{443*OVERSAMPLENR, 115},
{460*OVERSAMPLENR, 112},
{477*OVERSAMPLENR, 110},
{494*OVERSAMPLENR, 108},
{511*OVERSAMPLENR, 106},
{528*OVERSAMPLENR, 103},
{545*OVERSAMPLENR, 101},
{562*OVERSAMPLENR, 99},
{579*OVERSAMPLENR, 97},
{596*OVERSAMPLENR, 95},
{613*OVERSAMPLENR, 92},
{630*OVERSAMPLENR, 90},
{647*OVERSAMPLENR, 88},
{664*OVERSAMPLENR, 86},
{681*OVERSAMPLENR, 84},
{698*OVERSAMPLENR, 81},
{715*OVERSAMPLENR, 79},
{732*OVERSAMPLENR, 77},
{749*OVERSAMPLENR, 75},
{766*OVERSAMPLENR, 72},
{783*OVERSAMPLENR, 70},
{800*OVERSAMPLENR, 67},
{817*OVERSAMPLENR, 64},
{834*OVERSAMPLENR, 61},
{851*OVERSAMPLENR, 58},
{868*OVERSAMPLENR, 55},
{885*OVERSAMPLENR, 52},
{902*OVERSAMPLENR, 48},
{919*OVERSAMPLENR, 44},
{936*OVERSAMPLENR, 40},
{953*OVERSAMPLENR, 34},
{970*OVERSAMPLENR, 28},
{987*OVERSAMPLENR, 20},
{1004*OVERSAMPLENR, 8},
{1021*OVERSAMPLENR, 0}
};

endif

if (THERMISTORHEATER_0 == 6) || (THERMISTORHEATER_1 == 6) || (THERMISTORHEATER_2 == 6) || (THERMISTORBED == 6) // 100k Epcos thermistor

const short temptable_6[][2] PROGMEM = {
{28*OVERSAMPLENR, 250},
{31*OVERSAMPLENR, 245},
{35*OVERSAMPLENR, 240},
{39*OVERSAMPLENR, 235},
{42*OVERSAMPLENR, 230},
{44*OVERSAMPLENR, 225},
{49*OVERSAMPLENR, 220},
{53*OVERSAMPLENR, 215},
{62*OVERSAMPLENR, 210},
{73*OVERSAMPLENR, 205},
{72*OVERSAMPLENR, 200},
{94*OVERSAMPLENR, 190},
{102*OVERSAMPLENR, 185},
{116*OVERSAMPLENR, 170},
{143*OVERSAMPLENR, 160},
{183*OVERSAMPLENR, 150},
{223*OVERSAMPLENR, 140},
{270*OVERSAMPLENR, 130},
{318*OVERSAMPLENR, 120},
{383*OVERSAMPLENR, 110},
{413*OVERSAMPLENR, 105},
{439*OVERSAMPLENR, 100},
{484*OVERSAMPLENR, 95},
{513*OVERSAMPLENR, 90},
{607*OVERSAMPLENR, 80},
{664*OVERSAMPLENR, 70},
{781*OVERSAMPLENR, 60},
{810*OVERSAMPLENR, 55},
{849*OVERSAMPLENR, 50},
{914*OVERSAMPLENR, 45},
{914*OVERSAMPLENR, 40},
{935*OVERSAMPLENR, 35},
{954*OVERSAMPLENR, 30},
{970*OVERSAMPLENR, 25},
{978*OVERSAMPLENR, 22},
{1008*OVERSAMPLENR, 3}
};

endif

if (THERMISTORHEATER_0 == 7) || (THERMISTORHEATER_1 == 7) || (THERMISTORHEATER_2 == 7) || (THERMISTORBED == 7) // 100k Honeywell 135-104LAG-J01

const short temptable_7[][2] PROGMEM = {
{46*OVERSAMPLENR, 270},
{50*OVERSAMPLENR, 265},
{54*OVERSAMPLENR, 260},
{58*OVERSAMPLENR, 255},
{62*OVERSAMPLENR, 250},
{67*OVERSAMPLENR, 245},
{72*OVERSAMPLENR, 240},
{79*OVERSAMPLENR, 235},
{85*OVERSAMPLENR, 230},
{91*OVERSAMPLENR, 225},
{99*OVERSAMPLENR, 220},
{107*OVERSAMPLENR, 215},
{116*OVERSAMPLENR, 210},
{126*OVERSAMPLENR, 205},
{136*OVERSAMPLENR, 200},
{149*OVERSAMPLENR, 195},
{160*OVERSAMPLENR, 190},
{175*OVERSAMPLENR, 185},
{191*OVERSAMPLENR, 180},
{209*OVERSAMPLENR, 175},
{224*OVERSAMPLENR, 170},
{246*OVERSAMPLENR, 165},
{267*OVERSAMPLENR, 160},
{293*OVERSAMPLENR, 155},
{316*OVERSAMPLENR, 150},
{340*OVERSAMPLENR, 145},
{364*OVERSAMPLENR, 140},
{396*OVERSAMPLENR, 135},
{425*OVERSAMPLENR, 130},
{460*OVERSAMPLENR, 125},
{489*OVERSAMPLENR, 120},
{526*OVERSAMPLENR, 115},
{558*OVERSAMPLENR, 110},
{591*OVERSAMPLENR, 105},
{628*OVERSAMPLENR, 100},
{660*OVERSAMPLENR, 95},
{696*OVERSAMPLENR, 90},
{733*OVERSAMPLENR, 85},
{761*OVERSAMPLENR, 80},
{794*OVERSAMPLENR, 75},
{819*OVERSAMPLENR, 70},
{847*OVERSAMPLENR, 65},
{870*OVERSAMPLENR, 60},
{892*OVERSAMPLENR, 55},
{911*OVERSAMPLENR, 50},
{929*OVERSAMPLENR, 45},
{944*OVERSAMPLENR, 40},
{959*OVERSAMPLENR, 35},
{971*OVERSAMPLENR, 30},
{981*OVERSAMPLENR, 25},
{989*OVERSAMPLENR, 20},
{994*OVERSAMPLENR, 15},
{1001*OVERSAMPLENR, 10},
{1005*OVERSAMPLENR, 5}
};

endif

define TT_NAME(_N) temptable ## _N

define TT_NAME(_N) _TT_NAME(_N)

ifdef THERMISTORHEATER_0

#define heater_0_temptable TT_NAME(THERMISTORHEATER_0)
#define heater_0_temptable_len (sizeof(heater_0_temptable)/sizeof(*heater_0_temptable))

else

ifdef HEATER_0_USES_THERMISTOR

#error No heater 0 thermistor table specified

else // HEATER_0_USES_THERMISTOR

#define heater_0_temptable 0
#define heater_0_temptable_len 0

endif // HEATER_0_USES_THERMISTOR

endif

ifdef THERMISTORHEATER_1

#define heater_1_temptable TT_NAME(THERMISTORHEATER_1)
#define heater_1_temptable_len (sizeof(heater_1_temptable)/sizeof(*heater_1_temptable))

else

ifdef HEATER_1_USES_THERMISTOR

#error No heater 1 thermistor table specified

else // HEATER_1_USES_THERMISTOR

#define heater_1_temptable 0
#define heater_1_temptable_len 0

endif // HEATER_1_USES_THERMISTOR

endif

ifdef THERMISTORHEATER_2

#define heater_2_temptable TT_NAME(THERMISTORHEATER_2)
#define heater_2_temptable_len (sizeof(heater_2_temptable)/sizeof(*heater_2_temptable))

else

ifdef HEATER_2_USES_THERMISTOR

#error No heater 2 thermistor table specified

else // HEATER_2_USES_THERMISTOR

#define heater_2_temptable 0
#define heater_2_temptable_len 0

endif // HEATER_2_USES_THERMISTOR

endif

ifdef THERMISTORBED

#define bedtemptable TT_NAME(THERMISTORBED)
#define bedtemptable_len (sizeof(bedtemptable)/sizeof(*bedtemptable))

else

ifdef BED_USES_THERMISTOR

#error No bed thermistor table specified

endif // BED_USES_THERMISTOR

endif

endif //THERMISTORTABLES_H_

include "thermistortables.h"

define X_STEP_PIN 54

define X_DIR_PIN 55

define X_ENABLE_PIN 38

define X_MIN_PIN 3

define X_MAX_PIN 2

define Y_STEP_PIN 60

define Y_DIR_PIN 61

define Y_ENABLE_PIN 56

define Y_MIN_PIN 14

define Y_MAX_PIN 15

define Z_STEP_PIN 46

define Z_DIR_PIN 48

define Z_ENABLE_PIN 62

define Z_MIN_PIN 18

define Z_MAX_PIN 19

define E_STEP_PIN 26

define E_DIR_PIN 28

define E_ENABLE_PIN 24

define Q_STEP_PIN 36

define Q_DIR_PIN 34

define Q_ENABLE_PIN 30

define SDPOWER -1

define EXTRUDERS 3

define TEMP_SENSOR_AD595_OFFSET 0.0

define TEMP_SENSOR_AD595_GAIN 1.0

define THERMISTORHEATER_0 1

define THERMISTORHEATER_1 1

define THERMISTORHEATER_2 1

define HEATER_0_USES_THERMISTOR 1

define HEATER_1_USES_THERMISTOR 1

define HEATER_2_USES_THERMISTOR 1

static void *heater_ttbl_map[EXTRUDERS] = { (void *)heater_0_temptable

if EXTRUDERS > 1

                                       , (void *)heater_1_temptable
Enter fullscreen mode Exit fullscreen mode

endif

if EXTRUDERS > 2

                                       , (void *)heater_2_temptable
Enter fullscreen mode Exit fullscreen mode

endif

if EXTRUDERS > 3

#error Unsupported number of extruders

endif

};

static int heater_ttbllen_map[EXTRUDERS] = { heater_0_temptable_len

if EXTRUDERS > 1

                                        , heater_1_temptable_len
Enter fullscreen mode Exit fullscreen mode

endif

if EXTRUDERS > 2

                                        , heater_2_temptable_len
Enter fullscreen mode Exit fullscreen mode

endif

if EXTRUDERS > 3

#error Unsupported number of extruders

endif

};

#define PGM_RD_W(x) (short)pgm_read_word(&x)

define SDSS 53

define LED_PIN 13

define FAN_PIN 9

define PS_ON_PIN 12

define KILL_PIN -1

define HEATER_0_PIN 10

define HEATER_1_PIN 8

define TEMP_0_PIN 15 // ANALOG NUMBERING

define TEMP_1_PIN 14 // ANALOG NUMBERING

define TEMP_2_PIN 13 // ANALOG NUMBERING

void setup() {

pinMode(TEMP_0_PIN , INPUT);

pinMode(TEMP_1_PIN , INPUT);

pinMode(TEMP_2_PIN , INPUT);

pinMode(FAN_PIN , OUTPUT);

pinMode(HEATER_0_PIN , OUTPUT);

pinMode(HEATER_1_PIN , OUTPUT);

pinMode(LED_PIN , OUTPUT);

pinMode(X_STEP_PIN , OUTPUT);

pinMode(X_DIR_PIN , OUTPUT);

pinMode(X_ENABLE_PIN , OUTPUT);

pinMode(Y_STEP_PIN , OUTPUT);

pinMode(Y_DIR_PIN , OUTPUT);

pinMode(Y_ENABLE_PIN , OUTPUT);

pinMode(Z_STEP_PIN , OUTPUT);

pinMode(Z_DIR_PIN , OUTPUT);

pinMode(Z_ENABLE_PIN , OUTPUT);

pinMode(E_STEP_PIN , OUTPUT);

pinMode(E_DIR_PIN , OUTPUT);

pinMode(E_ENABLE_PIN , OUTPUT);

pinMode(Q_STEP_PIN , OUTPUT);

pinMode(Q_DIR_PIN , OUTPUT);

pinMode(Q_ENABLE_PIN , OUTPUT);

digitalWrite(X_ENABLE_PIN , LOW);

digitalWrite(Y_ENABLE_PIN , LOW);

digitalWrite(Z_ENABLE_PIN , LOW);

digitalWrite(E_ENABLE_PIN , LOW);

digitalWrite(Q_ENABLE_PIN , LOW);

Serial.begin(115200);

}

float analog2temp(int raw, uint8_t e) {

#ifdef HEATER_0_USES_MAX6675

if (e == 0)

{

 return 0.25 * raw;
Enter fullscreen mode Exit fullscreen mode

}

#endif

if(heater_ttbl_map[e] != 0)

{

float celsius = 0;

byte i;

short (tt)[][2] = (short ()[][2])(heater_ttbl_map[e]);

raw = (1023 * OVERSAMPLENR) - raw;

for (i=1; i<heater_ttbllen_map[e]; i++)

{

 if ((PGM_RD_W((*tt)[i][0]) > raw) && ((float)(PGM_RD_W((*tt)[i][0]) - PGM_RD_W((*tt)[i-1][0])) >0))

 {

   celsius = PGM_RD_W((*tt)[i-1][1]) +

     (raw - PGM_RD_W((*tt)[i-1][0])) *

     (float)(PGM_RD_W((*tt)[i][1]) - PGM_RD_W((*tt)[i-1][1])) /

     (float)(PGM_RD_W((*tt)[i][0]) - PGM_RD_W((*tt)[i-1][0]));

   break;

 }
Enter fullscreen mode Exit fullscreen mode

}

// Overflow: Set to last value in the table

if (i == heater_ttbllen_map[e]) celsius = PGM_RD_W((*tt)[i-1][1]);

return celsius;

}

return ((raw * ((5.0 * 100.0) / 1024.0) / OVERSAMPLENR) * TEMP_SENSOR_AD595_GAIN) + TEMP_SENSOR_AD595_OFFSET;

}

unsigned long prevMillis;

void loop () {

if (millis() %1000 <500)

digitalWrite(LED_PIN, HIGH);

else

digitalWrite(LED_PIN, LOW);

if (millis() %1000 <300) {

digitalWrite(HEATER_0_PIN, HIGH);

digitalWrite(HEATER_1_PIN, LOW);

digitalWrite(FAN_PIN, LOW);

} else if (millis() %1000 <600) {

digitalWrite(HEATER_0_PIN, LOW);

digitalWrite(HEATER_1_PIN, HIGH);

digitalWrite(FAN_PIN, LOW);

} else {

digitalWrite(HEATER_0_PIN, LOW);

digitalWrite(HEATER_1_PIN, LOW);

digitalWrite(FAN_PIN, HIGH);

}

if (millis() %2000 <1000) {

digitalWrite(X_DIR_PIN , HIGH);

digitalWrite(Y_DIR_PIN , HIGH);

digitalWrite(Z_DIR_PIN , HIGH);

digitalWrite(E_DIR_PIN , HIGH);

digitalWrite(Q_DIR_PIN , HIGH);

}

else {

digitalWrite(X_DIR_PIN , LOW);

digitalWrite(Y_DIR_PIN , LOW);

digitalWrite(Z_DIR_PIN , LOW);

digitalWrite(E_DIR_PIN , LOW);

digitalWrite(Q_DIR_PIN , LOW);

}

digitalWrite(X_STEP_PIN , HIGH);

digitalWrite(Y_STEP_PIN , HIGH);

digitalWrite(Z_STEP_PIN , HIGH);

digitalWrite(E_STEP_PIN , HIGH);

digitalWrite(Q_STEP_PIN , HIGH);

delay(1);

digitalWrite(X_STEP_PIN , LOW);

digitalWrite(Y_STEP_PIN , LOW);

digitalWrite(Z_STEP_PIN , LOW);

digitalWrite(E_STEP_PIN , LOW);

digitalWrite(Q_STEP_PIN , LOW);

if (millis() -prevMillis >500){

prevMillis=millis();

int t = analogRead( TEMP_0_PIN);

Serial.print("T0 ");

Serial.print(t);

Serial.print("/");

Serial.print(analog2temp(1024 - t,0),0);

Serial.print(" T1 ");

t = analogRead( TEMP_1_PIN);

Serial.print(t);

Serial.print("/");

Serial.print(analog2temp(1024 - t,1),0);

Serial.print(" T2 ");

t = analogRead( TEMP_2_PIN);

Serial.print(t);

Serial.print("/");

Serial.println(analog2temp(1024 - t,2),0);

}

}
/***

// auto fall back to MP3 if AAC file not available

define AAC_FILENAME "/44100.aac"

define MP3_FILENAME "/44100.mp3"

// #define MJPEG_FILENAME "/288_30fps.mjpeg"
// #define MJPEG_FILENAME "/320_30fps.mjpeg"

define MJPEG_FILENAME "/480_15fps.mjpeg"

// #define MJPEG_FILENAME "/480_30fps.mjpeg"

define FPS 15

// #define FPS 30
// #define MJPEG_BUFFER_SIZE (288 * 240 * 2 / 8)
// #define MJPEG_BUFFER_SIZE (320 * 240 * 2 / 8)

define MJPEG_BUFFER_SIZE (480 * 270 * 2 / 8)

define AUDIOASSIGNCORE 1

define DECODEASSIGNCORE 0

define DRAWASSIGNCORE 1

define SDMMC_D3 10 // SDMMC Data3 / SPI CS

define SDMMC_CMD 11 // SDMMC CMD / SPI MOSI

define SDMMC_CLK 12 // SDMMC CLK / SPI SCK

define SDMMC_D0 13 // SDMMC Data0 / SPI MISO

include

include

include

include

include

include

include

/*******************************************************************************

  • Start of Arduino_GFX setting ***************************************************************************/ #include #define GFX_BL 2 Arduino_DataBus *bus = new Arduino_ESP32LCD16( 48 / DC /, 45 / CS /, 47 / WR /, 21 / RD /, 5 / D0 /, 6 / D1 /, 7 / D2 /, 15 / D3 /, 16 / D4 /, 4 / D5 /, 8 / D6 /, 3 / D7 /, 46 / D8 /, 9 / D9 /, 1 / D10 /, 42 / D11 /, 39 / D12 /, 41 / D13 /, 40 / D14 /, 14 / D15 /); Arduino_GFX *gfx = new Arduino_NV3041A(bus, 17 / RST /, 0 / rotation /, true / IPS */); /*****************************************************************************
  • End of Arduino_GFX setting ******************************************************************************/

/* variables */
static int next_frame = 0;
static int skipped_frames = 0;
static unsigned long start_ms, curr_ms, next_frame_ms;

/* audio */

include "esp32_audio_task.h"

/* MJPEG Video */

include "mjpeg_decode_draw_task.h"

// pixel drawing callback
static int drawMCU(JPEGDRAW pDraw)
{
// Serial.printf("Draw pos = (%d, %d), size = %d x %d\n", pDraw->x, pDraw->y, pDraw->iWidth, pDraw->iHeight);
unsigned long s = millis();
gfx->draw16bitRGBBitmap(pDraw->x, pDraw->y, pDraw->pPixels, pDraw->iWidth, pDraw->iHeight);
total_show_video_ms += millis() - s;
return 1;
} /
drawMCU() */

void setup()
{
WiFi.mode(WIFI_OFF);

Serial.begin(115200);
// Serial.setDebugOutput(true);
// while(!Serial);
Serial.println("ESP32_4827A043");

ifdef GFX_EXTRA_PRE_INIT

GFX_EXTRA_PRE_INIT();

endif

Serial.println("Init display");
if (!gfx->begin())
{
Serial.println("Init display failed!");
}
gfx->fillScreen(BLACK);

ifdef GFX_BL

pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);

endif

Serial.println("Init I2S");
gfx->println("Init I2S");
esp_err_t ret_val = i2s_init(I2S_NUM_0, 44100, -1 /* MCLK /, 19 / SCLK /, 18 / LRCK /, 17 / DOUT /, -1 / DIN */);
if (ret_val != ESP_OK)
{
Serial.printf("i2s_init failed: %d\n", ret_val);
}
i2s_zero_dma_buffer(I2S_NUM_0);

Serial.println("Init FS");
gfx->println("Init FS");
// if (!LittleFS.begin(false, "/root"))
// if (!SPIFFS.begin(false, "/root"))
if (!FFat.begin(false, "/root"))

// SPIClass spi = SPIClass(HSPI);
// spi.begin(SDMMC_CLK, SDMMC_D0 /* MISO /, SDMMC_CMD / MOSI /, SDMMC_D3 / SS /);
// if (!SD.begin(SDMMC_D3 /
SS */, spi, 80000000))

// pinMode(SDMMC_D3 /* CS /, OUTPUT);
// digitalWrite(SDMMC_D3 /
CS /, HIGH);
// SD_MMC.setPins(SDMMC_CLK, SDMMC_CMD, SDMMC_D0);
// if (!SD_MMC.begin("/root", true)) /
1-bit SD bus mode */
{
Serial.println("ERROR: File system mount failed!");
gfx->println("ERROR: File system mount failed!");
}
else
{
bool aac_file_available = false;
Serial.println("Open AAC file: " AAC_FILENAME);
gfx->println("Open AAC file: " AAC_FILENAME);
// File aFile = LittleFS.open(AAC_FILENAME);
// File aFile = SPIFFS.open(AAC_FILENAME);
File aFile = FFat.open(AAC_FILENAME);
// File aFile = SD.open(AAC_FILENAME);
// File aFile = SD_MMC.open(AAC_FILENAME);
if (aFile)
{
aac_file_available = true;
}
else
{
Serial.println("Open MP3 file: " MP3_FILENAME);
gfx->println("Open MP3 file: " MP3_FILENAME);
// aFile = LittleFS.open(MP3_FILENAME);
// aFile = SPIFFS.open(MP3_FILENAME);
aFile = FFat.open(MP3_FILENAME);
// aFile = SD.open(MP3_FILENAME);
// aFile = SD_MMC.open(MP3_FILENAME);
}

if (!aFile || aFile.isDirectory())
{
  Serial.println("ERROR: Failed to open " AAC_FILENAME " or " MP3_FILENAME " file for reading");
  gfx->println("ERROR: Failed to open " AAC_FILENAME " or " MP3_FILENAME " file for reading");
}
else
{
  Serial.println("Open MJPEG file: " MJPEG_FILENAME);
  gfx->println("Open MJPEG file: " MJPEG_FILENAME);
  // File vFile = LittleFS.open(MJPEG_FILENAME);
  // File vFile = SPIFFS.open(MJPEG_FILENAME);
  File vFile = FFat.open(MJPEG_FILENAME);
  // File vFile = SD.open(MJPEG_FILENAME);
  // File vFile = SD_MMC.open(MJPEG_FILENAME);
  if (!vFile || vFile.isDirectory())
  {
    Serial.println("ERROR: Failed to open " MJPEG_FILENAME " file for reading");
    gfx->println("ERROR: Failed to open " MJPEG_FILENAME " file for reading");
  }
  else
  {
    Serial.println("Init video");
    gfx->println("Init video");
    mjpeg_setup(&vFile, MJPEG_BUFFER_SIZE, drawMCU,
                false /* useBigEndian */, DECODEASSIGNCORE, DRAWASSIGNCORE);

    Serial.println("Start play audio task");
    gfx->println("Start play audio task");
    BaseType_t ret_val;
    if (aac_file_available)
    {
      ret_val = aac_player_task_start(&aFile, AUDIOASSIGNCORE);
    }
    else
    {
      ret_val = mp3_player_task_start(&aFile, AUDIOASSIGNCORE);
    }
    if (ret_val != pdPASS)
    {
      Serial.printf("Audio player task start failed: %d\n", ret_val);
      gfx->printf("Audio player task start failed: %d\n", ret_val);
    }

    Serial.println("Start play video");
    gfx->println("Start play video");
    start_ms = millis();
    curr_ms = millis();
    next_frame_ms = start_ms + (++next_frame * 1000 / FPS / 2);
    while (vFile.available() && mjpeg_read_frame()) // Read video
    {
      total_read_video_ms += millis() - curr_ms;
      curr_ms = millis();

      if (millis() < next_frame_ms) // check show frame or skip frame
      {
        // Play video
        mjpeg_draw_frame();
        total_decode_video_ms += millis() - curr_ms;
        curr_ms = millis();
      }
      else
      {
        ++skipped_frames;
        Serial.println("Skip frame");
      }

      while (millis() < next_frame_ms)
      {
        vTaskDelay(pdMS_TO_TICKS(1));
      }

      curr_ms = millis();
      next_frame_ms = start_ms + (++next_frame * 1000 / FPS);
    }
    int time_used = millis() - start_ms;
    int total_frames = next_frame - 1;
    Serial.println("AV end");
    vFile.close();
    aFile.close();

    delay(200);

    int played_frames = total_frames - skipped_frames;
    float fps = 1000.0 * played_frames / time_used;
    total_decode_audio_ms -= total_play_audio_ms;
    // total_decode_video_ms -= total_show_video_ms;
    Serial.printf("Played frames: %d\n", played_frames);
    Serial.printf("Skipped frames: %d (%0.1f %%)\n", skipped_frames, 100.0 * skipped_frames / total_frames);
    Serial.printf("Time used: %d ms\n", time_used);
    Serial.printf("Expected FPS: %d\n", FPS);
    Serial.printf("Actual FPS: %0.1f\n", fps);
    Serial.printf("Read audio: %lu ms (%0.1f %%)\n", total_read_audio_ms, 100.0 * total_read_audio_ms / time_used);
    Serial.printf("Decode audio: %lu ms (%0.1f %%)\n", total_decode_audio_ms, 100.0 * total_decode_audio_ms / time_used);
    Serial.printf("Play audio: %lu ms (%0.1f %%)\n", total_play_audio_ms, 100.0 * total_play_audio_ms / time_used);
    Serial.printf("Read video: %lu ms (%0.1f %%)\n", total_read_video_ms, 100.0 * total_read_video_ms / time_used);
    Serial.printf("Decode video: %lu ms (%0.1f %%)\n", total_decode_video_ms, 100.0 * total_decode_video_ms / time_used);
    Serial.printf("Show video: %lu ms (%0.1f %%)\n", total_show_video_ms, 100.0 * total_show_video_ms / time_used);
Enter fullscreen mode Exit fullscreen mode

define CHART_MARGIN 64

define LEGEND_A_COLOR 0x1BB6

define LEGEND_B_COLOR 0xFBE1

define LEGEND_C_COLOR 0x2D05

define LEGEND_D_COLOR 0xD125

define LEGEND_E_COLOR 0x9337

define LEGEND_F_COLOR 0x8AA9

define LEGEND_G_COLOR 0xE3B8

define LEGEND_H_COLOR 0x7BEF

define LEGEND_I_COLOR 0xBDE4

define LEGEND_J_COLOR 0x15F9

    // gfx->setCursor(0, 0);
    gfx->setTextColor(WHITE);
    gfx->printf("Played frames: %d\n", played_frames);
    gfx->printf("Skipped frames: %d (%0.1f %%)\n", skipped_frames, 100.0 * skipped_frames / total_frames);
    gfx->printf("Time used: %d ms\n", time_used);
    gfx->printf("Expected FPS: %d\n", FPS);
    gfx->printf("Actual FPS: %0.1f\n\n", fps);

    int16_t r1 = ((gfx->height() - CHART_MARGIN - CHART_MARGIN) / 2);
    int16_t r2 = r1 / 2;
    int16_t cx = gfx->width() - r1 - 10;
    int16_t cy = r1 + CHART_MARGIN;

    float arc_start1 = 0;
    float arc_end1 = arc_start1 + max(2.0, 360.0 * total_read_audio_ms / time_used);
    for (int i = arc_start1 + 1; i < arc_end1; i += 2)
    {
      gfx->fillArc(cx, cy, r1, r2, arc_start1 - 90.0, i - 90.0, LEGEND_A_COLOR);
    }
    gfx->fillArc(cx, cy, r1, r2, arc_start1 - 90.0, arc_end1 - 90.0, LEGEND_A_COLOR);
    gfx->setTextColor(LEGEND_A_COLOR);
    gfx->printf("Read audio: %lu ms (%0.1f %%)\n", total_read_audio_ms, 100.0 * total_read_audio_ms / time_used);

    float arc_start2 = arc_end1;
    float arc_end2 = arc_start2 + max(2.0, 360.0 * total_decode_audio_ms / time_used);
    for (int i = arc_start2 + 1; i < arc_end2; i += 2)
    {
      gfx->fillArc(cx, cy, r1, r2, arc_start2 - 90.0, i - 90.0, LEGEND_B_COLOR);
    }
    gfx->fillArc(cx, cy, r1, r2, arc_start2 - 90.0, arc_end2 - 90.0, LEGEND_B_COLOR);
    gfx->setTextColor(LEGEND_B_COLOR);
    gfx->printf("Decode audio: %lu ms (%0.1f %%)\n", total_decode_audio_ms, 100.0 * total_decode_audio_ms / time_used);
    gfx->setTextColor(LEGEND_J_COLOR);
    gfx->printf("Play audio: %lu ms (%0.1f %%)\n", total_play_audio_ms, 100.0 * total_play_audio_ms / time_used);

    float arc_start3 = arc_end2;
    float arc_end3 = arc_start3 + max(2.0, 360.0 * total_read_video_ms / time_used);
    for (int i = arc_start3 + 1; i < arc_end3; i += 2)
    {
      gfx->fillArc(cx, cy, r1, r2, arc_start3 - 90.0, i - 90.0, LEGEND_C_COLOR);
    }
    gfx->fillArc(cx, cy, r1, r2, arc_start3 - 90.0, arc_end3 - 90.0, LEGEND_C_COLOR);
    gfx->setTextColor(LEGEND_C_COLOR);
    gfx->printf("Read video: %lu ms (%0.1f %%)\n", total_read_video_ms, 100.0 * total_read_video_ms / time_used);

    float arc_start4 = arc_end3;
    float arc_end4 = arc_start4 + max(2.0, 360.0 * total_show_video_ms / time_used);
    for (int i = arc_start4 + 1; i < arc_end4; i += 2)
    {
      gfx->fillArc(cx, cy, r1, r2, arc_start4 - 90.0, i - 90.0, LEGEND_D_COLOR);
    }
    gfx->fillArc(cx, cy, r1, r2, arc_start4 - 90.0, arc_end4 - 90.0, LEGEND_D_COLOR);
    gfx->setTextColor(LEGEND_D_COLOR);
    gfx->printf("Show video: %lu ms (%0.1f %%)\n", total_show_video_ms, 100.0 * total_show_video_ms / time_used);

    float arc_start5 = 0;
    float arc_end5 = arc_start5 + max(2.0, 360.0 * total_decode_video_ms / time_used);
    for (int i = arc_start5 + 1; i < arc_end5; i += 2)
    {
      gfx->fillArc(cx, cy, r2, 0, arc_start5 - 90.0, i - 90.0, LEGEND_E_COLOR);
    }
    gfx->fillArc(cx, cy, r2, 0, arc_start5 - 90.0, arc_end5 - 90.0, LEGEND_E_COLOR);
    gfx->setTextColor(LEGEND_E_COLOR);
    gfx->printf("Decode video: %lu ms (%0.1f %%)\n", total_decode_video_ms, 100.0 * total_decode_video_ms / time_used);
  }

  // delay(60000);
Enter fullscreen mode Exit fullscreen mode

ifdef GFX_BL

  // digitalWrite(GFX_BL, LOW);
Enter fullscreen mode Exit fullscreen mode

endif

  // gfx->displayOff();
  // esp_deep_sleep_start();
}
Enter fullscreen mode Exit fullscreen mode

}
}

void loop()
{
}

include "driver/i2s.h"

include "AACDecoderHelix.h"

include "MP3DecoderHelix.h"

define GAIN_LEVEL 0.8

static unsigned long total_read_audio_ms = 0;
static unsigned long total_decode_audio_ms = 0;
static unsigned long total_play_audio_ms = 0;

static i2s_port_t _i2s_num;
static esp_err_t i2s_init(i2s_port_t i2s_num, uint32_t sample_rate,
int mck_io_num, /!< MCK in out pin. Note that ESP32 supports setting MCK on GPIO0/GPIO1/GPIO3 only/
int bck_io_num, /!< BCK in out pin/
int ws_io_num, /!< WS in out pin/
int data_out_num, /!< DATA out pin/
int data_in_num /!< DATA in pin/
)
{
_i2s_num = i2s_num;

esp_err_t ret_val = ESP_OK;

i2s_config_t i2s_config;
i2s_config.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX);
i2s_config.sample_rate = sample_rate;
i2s_config.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT;
i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT;
i2s_config.communication_format = I2S_COMM_FORMAT_STAND_I2S;
i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1;
i2s_config.dma_buf_count = 8;
i2s_config.dma_buf_len = 160;
i2s_config.use_apll = false;
i2s_config.tx_desc_auto_clear = true;
i2s_config.fixed_mclk = 0;
i2s_config.mclk_multiple = I2S_MCLK_MULTIPLE_DEFAULT;
i2s_config.bits_per_chan = I2S_BITS_PER_CHAN_16BIT;

i2s_pin_config_t pin_config;
pin_config.mck_io_num = mck_io_num;
pin_config.bck_io_num = bck_io_num;
pin_config.ws_io_num = ws_io_num;
pin_config.data_out_num = data_out_num;
pin_config.data_in_num = data_in_num;

ret_val |= i2s_driver_install(i2s_num, &i2s_config, 0, NULL);
ret_val |= i2s_set_pin(i2s_num, &pin_config);

return ret_val;
}

static int _samprate = 0;
static void aacAudioDataCallback(AACFrameInfo &info, int16_t pwm_buffer, size_t len, void)
{
unsigned long s = millis();
if (_samprate != info.sampRateOut)
{
// log_i("bitRate: %d, nChans: %d, sampRateCore: %d, sampRateOut: %d, bitsPerSample: %d, outputSamps: %d, profile: %d, tnsUsed: %d, pnsUsed: %d",
// info.bitRate, info.nChans, info.sampRateCore, info.sampRateOut, info.bitsPerSample, info.outputSamps, info.profile, info.tnsUsed, info.pnsUsed);
i2s_set_clk(_i2s_num, info.sampRateOut /* sample_rate /, info.bitsPerSample / bits_cfg /, (info.nChans == 2) ? I2S_CHANNEL_STEREO : I2S_CHANNEL_MONO / channel /);
_samprate = info.sampRateOut;
}
size_t i2s_bytes_written = 0;
for (int i = 0; i < len; i++)
{
pwm_buffer[i] = pwm_buffer[i] * GAIN_LEVEL;
}
i2s_write(_i2s_num, pwm_buffer, len * 2, &i2s_bytes_written, portMAX_DELAY);
// log_i("len: %d, i2s_bytes_written: %d", len, i2s_bytes_written);
total_play_audio_ms += millis() - s;
}
static void mp3AudioDataCallback(MP3FrameInfo &info, int16_t *pwm_buffer, size_t len, void
)
{
unsigned long s = millis();
if (_samprate != info.samprate)
{
log_i("bitrate: %d, nChans: %d, samprate: %d, bitsPerSample: %d, outputSamps: %d, layer: %d, version: %d",
info.bitrate, info.nChans, info.samprate, info.bitsPerSample, info.outputSamps, info.layer, info.version);
i2s_set_clk(_i2s_num, info.samprate /* sample_rate /, info.bitsPerSample / bits_cfg /, (info.nChans == 2) ? I2S_CHANNEL_STEREO : I2S_CHANNEL_MONO / channel */);
_samprate = info.samprate;
}
size_t i2s_bytes_written = 0;
for (int i = 0; i < len; i++)
{
pwm_buffer[i] = pwm_buffer[i] * GAIN_LEVEL;
}
i2s_write(_i2s_num, pwm_buffer, len * 2, &i2s_bytes_written, portMAX_DELAY);
// log_i("len: %d, i2s_bytes_written: %d", len, i2s_bytes_written);
total_play_audio_ms += millis() - s;
}

static uint8_t _frame[MP3_MAX_FRAME_SIZE]; // MP3_MAX_FRAME_SIZE is smaller, so always use MP3_MAX_FRAME_SIZE

static libhelix::AACDecoderHelix _aac(aacAudioDataCallback);
static void aac_player_task(void *pvParam)
{
Stream *input = (Stream *)pvParam;

int r, w;
unsigned long ms = millis();
while (r = input->readBytes(_frame, MP3_MAX_FRAME_SIZE))
{
total_read_audio_ms += millis() - ms;
ms = millis();

while (r > 0)
{
  w = _aac.write(_frame, r);
  // log_i("r: %d, w: %d\n", r, w);
  r -= w;
}
total_decode_audio_ms += millis() - ms;
ms = millis();
Enter fullscreen mode Exit fullscreen mode

}
log_i("AAC stop.");

vTaskDelete(NULL);
}

static libhelix::MP3DecoderHelix _mp3(mp3AudioDataCallback);
static void mp3_player_task(void *pvParam)
{
Stream *input = (Stream *)pvParam;

int r, w;
unsigned long ms = millis();
while (r = input->readBytes(_frame, MP3_MAX_FRAME_SIZE))
{
total_read_audio_ms += millis() - ms;
ms = millis();

while (r > 0)
{
  w = _mp3.write(_frame, r);
  // log_i("r: %d, w: %d\n", r, w);
  r -= w;
}
total_decode_audio_ms += millis() - ms;
ms = millis();
Enter fullscreen mode Exit fullscreen mode

}
log_i("MP3 stop.");

vTaskDelete(NULL);
}

static BaseType_t aac_player_task_start(Stream *input, BaseType_t audioAssignCore)
{
_aac.begin();

return xTaskCreatePinnedToCore(
(TaskFunction_t)aac_player_task,
(const char *const)"AAC Player Task",
(const uint32_t)2000,
(void *const)input,
(UBaseType_t)configMAX_PRIORITIES - 1,
(TaskHandle_t *const)NULL,
(const BaseType_t)audioAssignCore);
}

static BaseType_t mp3_player_task_start(Stream *input, BaseType_t audioAssignCore)
{
_mp3.begin();

return xTaskCreatePinnedToCore(
(TaskFunction_t)mp3_player_task,
(const char *const)"MP3 Player Task",
(const uint32_t)2000,
(void *const)input,
(UBaseType_t)configMAX_PRIORITIES - 1,
(TaskHandle_t *const)NULL,
(const BaseType_t)audioAssignCore);
}

define READ_BUFFER_SIZE 1024

define MAXOUTPUTSIZE (MAX_BUFFERED_PIXELS / 16 / 16)

// #define MAXOUTPUTSIZE (480 / 4 / 16)

define NUMBER_OF_DECODE_BUFFER 3

define NUMBER_OF_DRAW_BUFFER 9

include

include

typedef struct
{
int32_t size;
uint8_t *buf;
} mjpegBuf;

typedef struct
{
xQueueHandle xqh;
JPEG_DRAW_CALLBACK *drawFunc;
} paramDrawTask;

typedef struct
{
xQueueHandle xqh;
mjpegBuf *mBuf;
JPEG_DRAW_CALLBACK *drawFunc;
} paramDecodeTask;

static JPEGDRAW jpegdraws[NUMBER_OF_DRAW_BUFFER];
static int _draw_queue_cnt = 0;
static JPEGDEC _jpegDec;
static xQueueHandle _xqh;
static bool _useBigEndian;

static unsigned long total_read_video_ms = 0;
static unsigned long total_decode_video_ms = 0;
static unsigned long total_show_video_ms = 0;

Stream *_input;

int32_t _mjpegBufSize;

uint8_t *_read_buf;
int32_t _mjpeg_buf_offset = 0;

TaskHandle_t _decodeTask;
TaskHandle_t _draw_task;
paramDecodeTask _pDecodeTask;
paramDrawTask _pDrawTask;
uint8_t *_mjpeg_buf;
uint8_t _mBufIdx = 0;

int32_t _inputindex = 0;
int32_t _buf_read;
int32_t _remain = 0;
mjpegBuf _mjpegBufs[NUMBER_OF_DECODE_BUFFER];

static int queueDrawMCU(JPEGDRAW *pDraw)
{
int len = pDraw->iWidth * pDraw->iHeight * 2;
JPEGDRAW *j = &jpegdraws[_draw_queue_cnt % NUMBER_OF_DRAW_BUFFER];
j->x = pDraw->x;
j->y = pDraw->y;
j->iWidth = pDraw->iWidth;
j->iHeight = pDraw->iHeight;
memcpy(j->pPixels, pDraw->pPixels, len);

// log_i("queueDrawMCU start.");
++_draw_queue_cnt;
xQueueSend(_xqh, &j, portMAX_DELAY);
// log_i("queueDrawMCU end.");

return 1;
}

static void decode_task(void *arg)
{
paramDecodeTask *p = (paramDecodeTask *)arg;
mjpegBuf *mBuf;
log_i("decode_task start.");
while (xQueueReceive(p->xqh, &mBuf, portMAX_DELAY))
{
// log_i("mBuf->size: %d", mBuf->size);
// log_i("mBuf->buf start: %X %X, end: %X, %X.", mBuf->buf[0], mBuf->buf[1], mBuf->buf[mBuf->size - 2], mBuf->buf[mBuf->size - 1]);
unsigned long s = millis();

_jpegDec.openRAM(mBuf->buf, mBuf->size, p->drawFunc);

// _jpegDec.setMaxOutputSize(MAXOUTPUTSIZE);
if (_useBigEndian)
{
  _jpegDec.setPixelType(RGB565_BIG_ENDIAN);
}
_jpegDec.setMaxOutputSize(MAXOUTPUTSIZE);
_jpegDec.decode(0, 0, 0);
_jpegDec.close();

total_decode_video_ms += millis() - s;
Enter fullscreen mode Exit fullscreen mode

}
vQueueDelete(p->xqh);
log_i("decode_task end.");
vTaskDelete(NULL);
}

static void draw_task(void *arg)
{
paramDrawTask *p = (paramDrawTask *)arg;
JPEGDRAW *pDraw;
log_i("draw_task start.");
while (xQueueReceive(p->xqh, &pDraw, portMAX_DELAY))
{
// log_i("draw_task work start: x: %d, y: %d, iWidth: %d, iHeight: %d.", pDraw->x, pDraw->y, pDraw->iWidth, pDraw->iHeight);
p->drawFunc(pDraw);
// log_i("draw_task work end.");
}
vQueueDelete(p->xqh);
log_i("draw_task end.");
vTaskDelete(NULL);
}

bool mjpeg_setup(Stream *input, int32_t mjpegBufSize, JPEG_DRAW_CALLBACK *pfnDraw,
bool useBigEndian, BaseType_t decodeAssignCore, BaseType_t drawAssignCore)
{
_input = input;
_mjpegBufSize = mjpegBufSize;
_useBigEndian = useBigEndian;

for (int i = 0; i < NUMBER_OF_DECODE_BUFFER; ++i)
{
_mjpegBufs[i].buf = (uint8_t *)malloc(mjpegBufSize);
if (_mjpegBufs[i].buf)
{
log_i("#%d decode buffer allocated.", i);
}
else
{
log_e("#%d decode buffer allocat failed.", i);
}
}
_mjpeg_buf = _mjpegBufs[_mBufIdx].buf;

if (!_read_buf)
{
_read_buf = (uint8_t *)malloc(READ_BUFFER_SIZE);
}
if (_read_buf)
{
log_i("Read buffer allocated.");
}

_xqh = xQueueCreate(NUMBER_OF_DRAW_BUFFER, sizeof(JPEGDRAW));
_pDrawTask.xqh = _xqh;
_pDrawTask.drawFunc = pfnDraw;
_pDecodeTask.xqh = xQueueCreate(NUMBER_OF_DECODE_BUFFER, sizeof(mjpegBuf));
_pDecodeTask.drawFunc = queueDrawMCU;

xTaskCreatePinnedToCore(
(TaskFunction_t)decode_task,
(const char *const)"MJPEG decode Task",
(const uint32_t)2000,
(void *const)&_pDecodeTask,
(UBaseType_t)configMAX_PRIORITIES - 1,
(TaskHandle_t *const)&_decodeTask,
(const BaseType_t)decodeAssignCore);
xTaskCreatePinnedToCore(
(TaskFunction_t)draw_task,
(const char *const)"MJPEG Draw Task",
(const uint32_t)2000,
(void *const)&_pDrawTask,
(UBaseType_t)configMAX_PRIORITIES - 1,
(TaskHandle_t *const)&_draw_task,
(const BaseType_t)drawAssignCore);

for (int i = 0; i < NUMBER_OF_DRAW_BUFFER; i++)
{
if (!jpegdraws[i].pPixels)
{
jpegdraws[i].pPixels = (uint16_t *)heap_caps_malloc(MAXOUTPUTSIZE * 16 * 16 * 2, MALLOC_CAP_DMA);
}
if (jpegdraws[i].pPixels)
{
log_i("#%d draw buffer allocated.", i);
}
else
{
log_e("#%d draw buffer allocat failed.", i);
}
}

return true;
}

bool mjpeg_read_frame()
{
if (_inputindex == 0)
{
_buf_read = _input->readBytes(_read_buf, READ_BUFFER_SIZE);
_inputindex += _buf_read;
}
_mjpeg_buf_offset = 0;
int i = 0;
bool found_FFD8 = false;
while ((_buf_read > 0) && (!found_FFD8))
{
i = 0;
while ((i < _buf_read) && (!found_FFD8))
{
if ((_read_buf[i] == 0xFF) && (_read_buf[i + 1] == 0xD8)) // JPEG header
{
// log_i("Found FFD8 at: %d.", i);
found_FFD8 = true;
}
++i;
}
if (found_FFD8)
{
--i;
}
else
{
_buf_read = _input->readBytes(_read_buf, READ_BUFFER_SIZE);
}
}
uint8_t *_p = _read_buf + i;
_buf_read -= i;
bool found_FFD9 = false;
if (_buf_read > 0)
{
i = 3;
while ((_buf_read > 0) && (!found_FFD9))
{
if ((_mjpeg_buf_offset > 0) && (_mjpeg_buf[_mjpeg_buf_offset - 1] == 0xFF) && (_p[0] == 0xD9)) // JPEG trailer
{
found_FFD9 = true;
}
else
{
while ((i < _buf_read) && (!found_FFD9))
{
if ((_p[i] == 0xFF) && (_p[i + 1] == 0xD9)) // JPEG trailer
{
found_FFD9 = true;
++i;
}
++i;
}
}

  // log_i("i: %d", i);
  memcpy(_mjpeg_buf + _mjpeg_buf_offset, _p, i);
  _mjpeg_buf_offset += i;
  int32_t o = _buf_read - i;
  if (o > 0)
  {
    // log_i("o: %d", o);
    memcpy(_read_buf, _p + i, o);
    _buf_read = _input->readBytes(_read_buf + o, READ_BUFFER_SIZE - o);
    _p = _read_buf;
    _inputindex += _buf_read;
    _buf_read += o;
    // log_i("_buf_read: %d", _buf_read);
  }
  else
  {
    _buf_read = _input->readBytes(_read_buf, READ_BUFFER_SIZE);
    _p = _read_buf;
    _inputindex += _buf_read;
  }
  i = 0;
}
if (found_FFD9)
{
  // log_i("Found FFD9 at: %d.", _mjpeg_buf_offset);
  if (_mjpeg_buf_offset > _mjpegBufSize)
  {
    log_e("_mjpeg_buf_offset(%d) > _mjpegBufSize (%d)", _mjpeg_buf_offset, _mjpegBufSize);
  }
  return true;
}
Enter fullscreen mode Exit fullscreen mode

}

return false;
}

bool mjpeg_draw_frame()
{
mjpegBuf *mBuf = &_mjpegBufs[_mBufIdx];
mBuf->size = _mjpeg_buf_offset;
// log_i("_mjpegBufs[%d].size: %d.", _mBufIdx, _mjpegBufs[_mBufIdx].size);
// log_i("_mjpegBufs[%d].buf start: %X %X, end: %X, %X.", _mjpegBufs, _mjpegBufs[_mBufId].buf[0], _mjpegBufs[_mBufIdx].buf[1], _mjpegBufs[_mBufIdx].buf[_mjpeg_buf_offset - 2], _mjpegBufs[_mBufIdx].buf[_mjpeg_buf_offset - 1]);
xQueueSend(_pDecodeTask.xqh, &mBuf, portMAX_DELAY);
++_mBufIdx;
if (_mBufIdx >= NUMBER_OF_DECODE_BUFFER)
{
_mBufIdx = 0;
}
_mjpeg_buf = _mjpegBufs[_mBufIdx].buf;
// log_i("queue decode_task end");

return true;
}

Top comments (0)