Docara wrote: Wed Aug 05, 2020 2:06 pm
...
I am currently trying to design and choose a MCU's for a narrow boat project in the UK, trouble is I really struggle with programming.
I can just about deal with the annoying ArduinoIDE and C is driving me nuts trying to learn it. Therefore, I will have to use a package which holds my hands and does 'stuff' for me - currently I use Flowcode for my PIC and AVR projects which fulfils my requirements (up till now).
I do not require massive computing power but low power, and good interrupt options, Touch and Comms.
...
Matt,
Before moving forward with Blue Pill, you really should document what about ArduinoIDE is driving you crazy; is it "C" syntax or the "IDE". If you have successfully worked on PIC & AVR chips, so, ARM is just another microcontroller technology.

- flowcontrol.jpg (25.54 KiB) Viewed 5723 times
Flowcode gives you the "C", so the transition from visual to C should be an easy transition... just a paradigm shift.
ArduinoIDE is deceptively simple: most novice programmers go wrong because their introduction is via YouTube and that fries their brains with useless methodology. Rather, one simply needs to envision a program in Arduino as a 5-step process:
1. Identify required libraries you will utilize,
2. Declare global variables to share
3. Put initialization(s) in the setup() area between braces { }
4. Put user defined requirements and function calls in loop() section between { }
5. Write functions in a logical manner and put them in IDE tabs logically grouped

- Engine Monitor.jpg (45.73 KiB) Viewed 5723 times
Section #1
Code: Select all
#include "./AnalogAverage.h" // Matrix summations
#include "./BATTERY.h" // Voltage and Current
#include "./THERMOCOUPLE.h" // Exhaust Gas temps left and right
#include "./ENGINE.h" // Coolent temp, Front cyl temp, Rear cyl temp, oil temp, oil pressure
#include "./FUEL.h" // Fuel tank level
Section #2
Code: Select all
// Type Variable Declarations for the main sketch tab
float temp = 0.00;
Section #3
Code: Select all
void setup() {
// analogReference(EXTERNAL) ; // A precision 5.00 Volt source OR other precision source
analogReference(DEFAULT) ;
Serial.begin(9600);
Serial.println() ;
// pins defined in THERMOCOUPLE.h
pinMode(addr_0, OUTPUT); pinMode(addr_1, OUTPUT); pinMode(addr_2, OUTPUT); pinMode(addr_3, OUTPUT);
digitalWrite(addr_0, LOW); digitalWrite(addr_1, LOW); digitalWrite(addr_2, LOW); digitalWrite(addr_3, LOW);
delay(50);
}
Section #4
Code: Select all
void loop() {
analog_0(); // A0 Water temperature
analog_1(); // A1 Oil temperature
analog_2(); // A2 Oil Pressure
analog_10(); // A10 Amps measured
analog_12(); // A12 Battery voltage measured
analog_15(); // A15 Fuel pressure
thermo_0(); // Exhaust Gas left
thermo_1(); // To be determined ... un-comment function in JSON tab
thermo_2(); // To be determined
thermo_3(); // To be determined
thermo_4(); // To be determined
thermo_5(); // To be determined
thermo_6(); // To be determined
thermo_7(); // To be determined
thermo_8(); // To be determined
thermo_9(); // To be determined
thermo_10(); // To be determined
thermo_11(); // To be determined
delay(5000);
/* thermo_12(); // To be determined
thermo_13(); // To be determined
thermo_14(); // To be determined
thermo_15(); // To be determined
*/
}
Section #5 Now, we write matching code for functions in the tabs, grouping if we desire. Because I often publish my silly little projects, I choose to "encapsulate" libraries within my code to make it easier for readers to get a project downloaded and working.
Example Tab: JSON
Code: Select all
/* Faux JSON file format https://groups.google.com/forum/#!topic/node-red/pvY36rlRUdI */
void analog_0(void) {
float temp = EngineCoolantTemp();
Serial.print("{\"H2O_Tmp\":"); Serial.print(temp); Serial.print (",");
}
void analog_1(void) { /* Oil temperature */
float temp = float(EngOilTemp() );
Serial.print ("\"Oil_Tmp\":"); Serial.print(temp); Serial.print(",");
return;
}
void analog_2(void) { /* Engine Oil Pressure */
float temp = float (EngineOilPres());
Serial.print("\"Oil_Prs\":"); Serial.print(temp); Serial.print(",");
return;
}
void analog_10(void) { /* Amps measured */
float temp = float (BatteryAmps());
Serial.print("\"Current\":"); Serial.print(temp); Serial.print(",");
return;
}
void analog_12(void) { /* Battery voltage measured */
float temp = float (BatteryVoltage());
Serial.print("\"Voltage\":"); Serial.print(temp); Serial.print(",");
return;
}
void analog_15(void) { /* Gasoline fuel pressure */
float temp = fuelPressure(); /* fuel pressure is a fp math function */
Serial.print("\"Gas_Prs\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_0(void) { /* Exhaust Gas left */
int temp = float (thermocouple_channel( 0));
Serial.print("\"EGT_1\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_1(void) {
int temp = float (thermocouple_channel( 1));
Serial.print("\"EGT_2\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_2(void) {
int temp = float (thermocouple_channel( 2));
Serial.print("\"EGT_3\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_3(void) {
int temp = float (thermocouple_channel( 3));
Serial.print("\"EGT_4\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_4(void) {
int temp = float (thermocouple_channel( 4));
Serial.print("\"EGT_5\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_5(void) {
int temp = float (thermocouple_channel( 5));
Serial.print("\"EGT_6\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_6(void) {
int temp = float (thermocouple_channel( 6));
Serial.print("\"EGT_7\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_7(void) {
int temp = float (thermocouple_channel( 7));
Serial.print("\"EGT_8\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_8(void) {
int temp = float (thermocouple_channel( 8));
Serial.print("\"EGT_9\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_9(void) {
int temp = float (thermocouple_channel( 9));
Serial.print("\"EGT_10\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_10(void) {
int temp = float (thermocouple_channel(10));
Serial.print("\"EGT_11\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_11(void) {
int temp = float (thermocouple_channel(11));
Serial.print("\"EGT_12\":"); Serial.print(temp); Serial.print("}\n");
return;
}
// ***** NOTE: YOU MUST UNCOMMENT IN THE MAIN TAB THE CALLING ROUTINE AND UNCOMMENT+EDIT TO PROVIDE NODERED WITH A NEW LABEL *****
/*void thermo_12(void) {
float temp = float (thermocouple_channel(12));
Serial.print("\"EGT_13\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_13(void) {
float temp = float (thermocouple_channel(13));
Serial.print("\"EGT_14\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_14(void) {
float temp = float (thermocouple_channel(14));
Serial.print("\"EGT_15\":"); Serial.print(temp); Serial.print(",");
return;
}
void thermo_15(void) {
float temp = float (thermocouple_channel(15));
Serial.print("\"EGT_16\":"); Serial.print(temp); Serial.print(",");
return;
}
Example Tab: THERMOCOUPLE.h
Code: Select all
#include "./MAX31855.h" // Local (embedded) library
int thermoDO = 51; // SPI Data Out
int thermoCS_1 = 52; // first EGT thermocouple amp Chip Select
int thermoCLK = 53; // common SPI clock to both 31855s
int thermoCS_2 = 50; // second EGT thermocouple amp Chip Select used in Europa design
int8_t addr_0 = 36; // 2^0 Addressline 0 going to analog mux
int8_t addr_1 = 34; // 2^1 Addressline 1 going to analog mux
int8_t addr_2 = 32; // 2^2 Addressline 2 going to analog mux
int8_t addr_3 = 30; // 2^3 Addressline 3 going to analog mux
/* CONCEPT
* A single MAX31855 chip will be used in conjunction (front-ended) by a 16 channel analog switch. channel_address_ 0-3 will be set HIGH/LOW
* to represent 0 through 15 address. Then, after settling delay(?) the thermocouple object will be called similarily to below. Address will
* be incremented, allowed to settle, and the thermocouple object called again. These calls must take place from within tab JSON and a small
* function created so it can be called from the main program loop on tab: Engine_Monitor_1. Each JSON function must print a unique identifier
* so that the downstream CodeRed program can select the tag, convert to a numeric and assign a label.
*/
MAX31855 thermocouple_(thermoCLK, thermoCS_2, thermoDO);
// ________________________________________________________________________SPI bus #1
float thermocouple_channel( int mux_address) {
switch(mux_address) {
case 0:
digitalWrite(addr_0, LOW); digitalWrite(addr_1, LOW); digitalWrite(addr_2, LOW); digitalWrite(addr_3, LOW);
break;
case 1:
digitalWrite(addr_0, HIGH); digitalWrite(addr_1, LOW); digitalWrite(addr_2, LOW); digitalWrite(addr_3, LOW);
break;
case 2:
digitalWrite(addr_0, LOW); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, LOW); digitalWrite(addr_3, LOW);
break;
case 3:
digitalWrite(addr_0, HIGH); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, LOW); digitalWrite(addr_3, LOW);
break;
case 4:
digitalWrite(addr_0, LOW); digitalWrite(addr_1, LOW); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, LOW);
break;
case 5:
digitalWrite(addr_0, HIGH); digitalWrite(addr_1, LOW); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, LOW);
break;
case 6:
digitalWrite(addr_0, LOW); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, LOW);
break;
case 7:
digitalWrite(addr_0, HIGH); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, LOW);
break;
case 8:
digitalWrite(addr_0, LOW); digitalWrite(addr_1, LOW); digitalWrite(addr_2, LOW); digitalWrite(addr_3, HIGH);
break;
case 9:
digitalWrite(addr_0, HIGH); digitalWrite(addr_1, LOW); digitalWrite(addr_2, LOW); digitalWrite(addr_3, HIGH);
break;
case 10:
digitalWrite(addr_0, LOW); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, LOW); digitalWrite(addr_3, HIGH);
break;
case 11:
digitalWrite(addr_0, HIGH); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, LOW); digitalWrite(addr_3, HIGH);
break;
case 12:
digitalWrite(addr_0, LOW); digitalWrite(addr_1, LOW); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, HIGH);
break;
case 13:
digitalWrite(addr_0, HIGH); digitalWrite(addr_1, LOW); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, HIGH);
break;
case 14:
digitalWrite(addr_0, LOW); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, HIGH);
break;
case 15:
digitalWrite(addr_0, HIGH); digitalWrite(addr_1, HIGH); digitalWrite(addr_2, HIGH); digitalWrite(addr_3, HIGH);
break;
}
delay(75);
float temp = 0.00;
double c = thermocouple_.readCelsius();
if (isnan(c)) {
// error code here
} else {
temp = thermocouple_.readInternal() ;
temp = thermocouple_.readFarenheit() ;
}
return (temp) ;
}
List of files with extensions:

- Filelist.jpg (66.21 KiB) Viewed 5721 times
Arduino handles the ".h/.cpp" and ".ino" differently: ".ino" files are concatenated to the main_sketch".ino" before feeding to the preprocessor. This is done to facilitate automatic function prototyping.
Good luck,
Ray
https://www.hackster.io/rayburne/projects