Comments (15)
100% yes! I will for sure be adding copious comments to the code, and maybe a little more overview on the wiki (though I tend to prefer code comments over separate documents since it involves less cross referencing). This next week is especially busy for me so I won't get a lot of time until later in the month, but I'll leave this issue open to remind me.
For the short term, a couple highlights of what's different from the previous version:
MoppyCore.cpp
is basically just an extension of the configuration and a convenient point for swapping out e.g. Floppy Drives for a Robo-Xylophone without having to have multiple Arduino sketches. It's also where thesetup()
andloop()
functions live- Anything in MoppyNetworks (for now primarily just
MoppySerial.*
is the part of the code that get executed in theloop()
function to receive and send serial communications. MoppyNetworks are given a pointer to a systemMessage handler (for things like start/stop/reset) and a deviceMessage handler (for note on/off messages). When messages are received from the network (serial port) the MoppyNetwork class will call the appropriate handler. - Anything in MoppyInstruments (for now just
FloppyDrives.*
) implements the two handlers above (system and device), and is responsible for driving whatever instrument is connected to the Arduino (as well as any more complex logic like pitch bending or solenoid timing).
For the L298N modifications, you'll probably looking mostly at the MoppyInstruments section (from my understanding of how they work, which is, admittedly, very brief). I'd recommend basically copying FloppyDrives.*
to your own class (L298N.*
?) and implementing the changes there. That way it's easy to swap out the constructor in MoppyCore.cpp
to switch between the default Floppy Drive implementation and the L298N implementation.
from moppy2.
Yeah, the mapper thing's going to solve an awful lot of requests / problems! π
The step thing has gotten a little complex, but I'll see if I can't provide some additional insight (some of this you'll no doubt already know, but in case it's helpful to others-- I'll probably just copy this into the documentation on the wiki):
The frequency with which the floppy drive moves its head equates to the frequency of the note you hear. So for the note A2 the head takes steps at 110Hz. Because we're using loops and counters to time the steps we need to get the inverse frequency, or period, for the note. Again for A2 this is 0.0090909 seconds or about 9091 microseconds between steps. This is the number stored in the notePeriods
array in MoppyInstrument.h
.
We could just do an endless loop and call micros()
over and over to wait for 9091 microseconds to pass (a little bit like in startupsound). However that quickly gets confusing for playing many different note frequencies but more importantly it doesn't allow any free processor cycles for reading and writing to the serial port. So instead, we're using an interrupt function (via the TimerOne library) that will interrupt any running code periodically after a specified period and execute a function (for our case the tick()
function). We need to allow ample time between interrupts for both the tick()
function to complete its work and to give the processor time to read/write to the serial port, so I've picked 40 microseconds between interrupts (this is the number specified as TIMER_RESOLUTION
in MoppyInstrument.h
).*
Since the tick()
function is only going to trigger every 40 microseconds, we don't really need to worry about anything more granular (i.e. there's no difference between 9091 and 9093 microseconds if we're only checking every 40 microseconds anyway). So to simplify things a bit further, we can start defining periods in "Ticks" instead of microseconds. So our friend the A2 can now be described as having 227 Ticks between steps instead of 9091 microseconds.
The floppy drive head takes a step on the falling edge of the signal sent to it (that is, when the voltage of the Step pin drops from 5v to 0v). In order to take a second step, the pin needs to be brought back up to 5v again before we can create another falling edge. For the best signal clarity, we want to keep these rising and falling edges as far apart as we can. Calling togglePin()
generates a falling edge every other invocation, so in order to generate falling edges at our desired frequency we need to call togglePin()
at twice that frequency (i.e. with half the period). The noteTicks
array stores the results of all this math which boils down to (period/resolution)/2, or for A2 (9091/40)/2 = 114 Ticks between calls to togglePin()
.
Actually tracking the state of each drive is just normal loops and counters after the math above is done. When a NoteOn event comes in, we put the value from noteTicks
into the currentPeriod
array at the index representing the drive we want to play the note on. Each time tick()
is called, we increment that same index in the currentTick
array by one. When the value in currentTick
reaches the value in currentPeriod
, we call togglePin()
, reset currentTick
to 0, and start over.
Apologies if that was a bit verbose, but better extra documentation that not enough. :P
* The resolution affects the accuracy of the notes being played. For A2 = 110Hz, we actually end up playing 109.65Hz. It gets worse at higher frequencies; an A4 = 440Hz comes out at 446.4Hz. Still closer to A than A#, but the next step down with 40 microsecond resolution is 431Hz which is even worse. Higher resolution would improve note accuracy but runs the risk of overlapping interrupts or not enough cycles for serial processing.
from moppy2.
I'll make these changes as soon as I can. Thanks for the advices! I also plan on making a completely different Floppy instrument: One Arduino per channel, and the velocity of the note would change the amount of drive that play the note. Would that be possible with the current Java code ?
from moppy2.
Thanks, I'll wait for the comments! I learned a lot since I made my first Moppy personal modification! You're going to see me alot here (and maybe in pull requests?) ;)
from moppy2.
Great! One of my main goals for 2.0 is to make it a lot easier for me to pull contributions to the library.
I just pushed some updates to add some additional comments to the Arduino code, let me know if those help out (and what might be missing that would help you figure out what you need in order to make changes).
from moppy2.
Comments do help a lot, but I'm still trying to figure out how to determine if a step must be done. (like, the condition, not just toggling a pin state)
btw: Holly shit, that mapper thing is EXACTLY what I was hoping for, what a good start!
from moppy2.
Finally, I managed to understand the code! This seems very clear to me now, I'm gonna come up with a modification soon, and I'll make it in a way that does not add any library for the L298N. Thanks a lot again, it was very helpful :)
from moppy2.
Hey,
I made the code for the L298N and pushed it to my fork : https://github.com/Lothean/Moppy2
It is supposed to work (although I don't access to my hardware at the moment..)
One problem that I've noticed is that changing the instrument does not appear simple:
- It requires edit in a config file (which I didn't modified on Github because I'm waiting for you to tell us how we are supposed to edit it)
- If I let both instruments in the MoppyInstruments folder, some variables are declared twice and the Arduino IDE refuses to compile the program.
Can you take a look at my (probably badly made) code and tell me if there's anything wrong that could create issues with Moppy ?
Thanks!
from moppy2.
I took a quick look (I'm not super familiar with L298Ns so I'll just have to trust that those parts are fine :P ), and it looks generally good. To address your two questions first:
- You'll change the instrument by modifying
MoppyCore.cpp
to replace:
#include "src/MoppyInstruments/FloppyDrives.h"
FloppyDrives instrument = FloppyDrives();
with
#include "src/MoppyInstruments/L298N.h"
L298N instrument = L298N();
And ideally instead of replacing it outright, you could add the two L298N lines commented out below the FloppyDrive lines. Basically, the "default" for the code base will be the FloppyDrives and it'll be up to the end user to comment/uncomment the appropriate lines there to configure for their instrument.
-
The variable clash is my fault (and my lack of C++ experience). All the variables in
FloppyDrives.cpp
andL298N.cpp
should also be declared under their respective namespaces (e.g.FloppyDrives::currentPosition
instead of justcurrentPosition
. You're welcome to take care of that for L298N whenever, though I'll try to fix that for FloppyDrives the next time I'm working on the code since I'm also going to add a new instrument class (and would have run into the same issues you did). -
And one additional thing I noticed, rather than divide by 2 for the noteDoubleTicks only to have to multiply by 2 again during your ticks, we should just add a new array to MoppyInstrument named noteTicks that doesn't divide by 2 (you can just copy and paste the whole thing there and replace DOUBLE_T_RESOLUTION with RESOLUTION. It makes that file even more cumbersome, but cuts down on repetitive math that has to be executed during ticks.
Generally looks awesome though! As soon as I get around to fixing the FloppDrive namespace issue and you get a chance to test on your hardware we can merge it into mainline :)
from moppy2.
The Java code would need to start sending velocity information along with the note information in the MoppyMessages (there'd need to be another byte). Not too hard to do, but would need to be done. I'll add an issue for it.
from moppy2.
Hey,
Code seems to be working, but with the little time that I had, I only managed to make it work on Channel 1, no idea why nothing was playing on the others. Maybe I'm not familiar enough with the new software.
I tried during the last couple of hours to declare the variables under their namespace; but it's easier said than done for me... I was not able to do it. I uploaded the new code in case somebody needs it, but without any garantee that it's good.
I'm working on a modification of the L298N code which will reduce the amount of bridges that can be connected on the Arduino, but allows more motors to be supported;
L298N "Low Power" will allow the bridge to be completely disabled when no step is being done (and thus, remove the "stand by" current), but will use 2 more I/O pins per bridge. I might not push that one if it seems pointless to others, but it helped me a lot when I had to deal with extreme temperatures on my L298N. So if someone needs it, just ask :)
from moppy2.
I meant to fix the namespace thing this weekend but got distracted by Cities: Skylines π
Just made a commit to mainline that fixes the issue for FloppyDrives.cpp
, you should be able to follow the pattern for L298N.cpp
to get it working.
Just about to see if I can't figure out what's up with the channel 1 only thing, but gotta learn a bit about the L298 (and have some food).
from moppy2.
Hmm, I couldn't see anything that looked like it would cause issues for not-channel 1 so it might be an issue on the controller app side (either in the mapper configuration or with the program itself).
Also, in my experience most people are looking for ways to add more motors and more floppy drives rather than less :P Power does always end up being a problem though because no one wants to provide a separate power supply for the drives (which isn't even that hard!)
If you still can't get the channel 1 bit working after fixing the namespaces, maybe post a screenshot of the controller app configuration and I'll see if anything looks amiss.
from moppy2.
Code is done, is working, and I submitted it!
I've declared all variables under their namespace and all channels work.
#11
from moppy2.
All merged! I added a limiter to the FloppyDrives code, but those higher notes will be really helpful for anyone using stepper motors.
Congrats on being the first Moppy2 pull!
(Closing this thread as being specific to adding L298N support, but feel free to open a new one for discussion or other questions)
from moppy2.
Related Issues (20)
- ...Android π HOT 4
- Windows Java Runtime Error HOT 2
- MoppyGUI wont connect to arduino HOT 2
- Floppy drive doesn't play music or startup tone HOT 13
- Compilation error: 'TIMER_RESOLUTION' was not declared in this scope HOT 7
- Nothing happens HOT 1
- code not compilation HOT 4
- Notes per channels HOT 1
- MoppyControlGUI.bat crashes HOT 10
- Default Sub-Address Script is Wrong
- Π€Π»ΠΎΠΏΠΏΠΈ HOT 1
- ControlGUI sends mdi data to serial, board serial led indicates data comes but the floppy motor doesn't move HOT 10
- Startup Sound should default to true HOT 1
- ESP32 support HOT 2
- Issue with MoppyControlGUI HOT 9
- Using without GUI ? HOT 8
- Error when uploading to Arduino R3 HOT 32
- .Bat file not openning correctly HOT 1
- Checking COM port in Network Bridges list causes error - Failed to open serialPort HOT 5
- How to connect fdd to esp8266 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from moppy2.