Hello all!
I would like to start off by saying I am not asking anyone to spend their time writing code for me for free. I will and have done research and just cant wrap my head around this.
Having said that here is what i am trying to do. I experiment with motors, generators and basically electromechanical devices. Up till now i have used many other means and circuits to pulse coils or connect coils at certain intervals but i have to design something new for every machine. One of the key aspects of the generators and such that i work with is a very clean make and break contact (brushes or relays) because transistors and mosfets take sometimes multiple microsends to be fully on / fully off and that does not suit the experiments. instead of making complicated contacts or circuits to have a switch at a certain point i want to make a controller that can sense the location of a magnet on a flywheel and be able to use the data to turn on or off relays at a given point. Another thing that is important is to be able to display the data on an oled because the entire point is to be able to adjust parameters and be able to correlate those parameters to the effects in the machine.
main example of what I am trying to do is this. I have a pulse motor with a rotor with 4 magnets, and one drive coil. I want to be able to know when the magnet is at Top Dead Center (TDC) meaning exactly at the center of the coil. From there I want to be able to offset a value so that i can make a relay close at (for example) 3 degrees after TDC untill a max of half the period (half way between the magnets). I need that to be adjustable "on the fly" so to be able to adjust and see the effects that is has on the motor. The problems I have a trouble wrapping my head around are: 1 I dont really care about the "speed up" part, seeing as when the motor is accelerating to top speed every revolution the pulse width and period will be different until they level out. but even at top speed if i change something that causes acceleration if the acceleration is a lot then I have to measure calculate and adjust the timing "all" between the magnets. given the desire to have a 4 magnet rotor with a top speed of 4000 max that is a period of 3.759 miliseconds. in that amount of time i need to calculate the pulse width to know where the center of the magnet is (width /2 ) use that to set a value for TDC and have an offset for how far from TDC i want to turn on the switch and how long the switch will stay on. SO basically it is a must to be able to do everything measurement wise within that time frame. The motor will "probably" have a max of 2500 rpm but i am going with 4000 to leave room for the unexpected. #2 because i need to display the results on an oled I am wondering if i should use two linked arduinos with one doing the sensor readings and relay that information to a second which will do the calculation and switching. That is because i simly cannot think of a way to figure out how long it takes for the code to execute therefore I have no idea if 3.759 miliseconds would be enough time. That also leads to the fact that if i want the switch to happen only a few degrees past TDC there would only be 41.76 microseconds (at theoretical top speed) to calculate per degree away from TDC so if i wanted to switch on a coil when the magnet is 2 degrees past TDC i would only have roughly 82 microseconds to sense the magnet (rising pulse on an interrupt from a hall sensor) add 1/2 the previous pulse width to find TDC add the offset so it turns on the coil at 2 degrees and use the previous period measurment to adjust the "on time" of the coil so it turns off at a variable amount between TDC and half the period.
So, what I am thinking of is this: If I use one arduino with an interrupt to set a Micros() value (lets say T1) when the hall sensor senses a magnet (rising edge), and senses when the magnet is past (T2 - falling edge) and the next magnet (T3 next rising edge) . I can relay those values to the second arduno to be the "calculator", "display" and the "output" and use T3 - T1 to find the period....T2 - T1 to find the pulse width which would leave the first arduino alone and let it sense everything precisely with basically only the interrupt to set the values and the IIC code to relay the data values to a second arduno. the second arduino would do the calculations and set the output values of TDC + offset to turn on the relay at a variable point and TDC + some variable to turn off the relay at a certain point, and also update the oled wich I only need updated every second or so. So does this sound feasible or am i completely barking up the wrong arduino?
Like i said before. I will do my research, But if anyone sees a problem with this idea or has ANY pointers on how to implement this in an easy fashion I would GREATLY appreciate any input.
At the current time I have a sketch I have built up be copying sections from multiple others to simply be able to read a hall sensor and find the period and calculate rpm. I believe it calculates based on a 2 pulse per revolution rotor, but that's simply because i am more focused on the other aspects and just haven't modified it for a 4 magnet rotor. when I can figure out whether i will need two arduinos or if it can be done with one i will write up a new code and post it so anybody that is feeling helpful can tell me if i am being an idiot. Thank you in advance to anybody that can help me think this through more clearly!
the current simple sketch for rpm measurment is this
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_MOSI 9
#define OLED_CLK 10
#define OLED_DC 11
#define OLED_CS 12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
#define SSD1306_LCDHEIGHT 64
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
int refsig = 200; //for converting the analog signal coming from hall sensor to digital through arduino code
int val;//the digital value of the incoming analog signals
int prev_val = 0;
int t, cur_t; //time variables
void setup() {
Serial.begin(115200);
pinMode(A0, INPUT);
display.begin(SSD1306_SWITCHCAPVCC);
display.display();
delay(2000);
// Clear the buffer.
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.setTextColor(WHITE);
}
void loop() {
int sig = analogRead(A0); //read raw value of hall sensor
if (sig > refsig) val = HIGH; //when value of hall sensor is above refsig sets val as digital high
else val = LOW; // if not above refsig sets val to digital low
if (prev_val == 0 && val == 1) { //if the prev_val was low and val goes high it has sensed the rising edge
cur_t = micros();
display.setCursor(0, 0);
display.print("RPM: ");
display.println(1000000 * 60 / (cur_t - t)); //print the rpm
display.display(); //you have to tell the display to...display
delayMicroseconds(2);
display.clearDisplay();
t = micros(); // sets time so the next loop around after reading the value cur_t - t =time elapsed between pulses
}
}
Moderator added code tags