Last active
October 21, 2023 01:07
-
-
Save juanmf/d756e2fbe794934287717b0444440692 to your computer and use it in GitHub Desktop.
Writes a CSV waveform.csv to local dir meant to import in a function generator. Merging specified frequencies. See https://gist.github.com/juanmf/2fd9ae5a6f7a6bfe851c6c699b98e8d1 for output sample. use Junctek windows app to upload to device http://www.junteks.com/newsinfo/835494.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## | |
# Writes a CSV waveform.csv to local dir meant to import in a function generator. | |
# The wave is meant to be input in a highside bridge switching a coil to create a BEMF | |
# on every LOW (0). | |
# It merges several frequencies together by adding a LOW (trigger BEMF impulse) at the start of every | |
# cycle of included frequencies. Very much like swing seats you push only at the beggining of each cycle, | |
# each with a different period. | |
# Selected Frequencies are in line with the equation (Planck * ϕ ^ N) | |
## | |
## | |
# Ok after a lot of search found the JDS8000 CSV format, has 8192 points, one column. | |
# Junctek csv | |
# 0 | |
# 0.0035 | |
# ... | |
## | |
import csv | |
import numpy | |
# Frequencies, All corresponding to wave lengths that are GoldenRatio exponents of plank | |
# (p * ϕ^n) n=[199, 200, 202, 203, 205, 208], closely matching Schumann Harmonics and brain waves. | |
# | |
# 47.8377133094 Hz 2.09E-02 0.0209040092 | |
# 29.5653327693 Hz 3.38E-02 0.0338233974 | |
# 11.2929522292 Hz 8.86E-02 0.0885508041 | |
# 6.9794283109 Hz 1.43E-01 0.1432782107 | |
# 2.6659043927 Hz 3.75E-01 0.3751072254 | |
# 0.6293346582 mHz 1.59E+00 1.5889797057 | |
# | |
# Frequencies in Hz | |
# All Negentropic frequencies above Schumann/Brain Freqs, up to max 10,000 Hz found in Rife lists. | |
# Leaving a safe gap from brain waves bellow | |
# f13 = 9519.9453330204 # makes file too heavy. | |
# f12 = 5883.6497868471 # makes file too heavy. | |
f11 = 3636.2955461724 | |
f10 = 2247.3542406742 | |
f9 = 1388.9413054978 | |
# (close match) by Dan's Equation. | |
f8 = 858.4129351762 # Rife: 852Hz (rise awareness) | |
f7 = 530.5283703214 # Rife 528Hz (love/healing) | |
# Aligned with brain and Schumann | |
f6 = 47.8377133094 | |
f5 = 29.5653327693 | |
f4 = 11.2929522292 | |
f3 = 6.9794283109 | |
f2 = 2.6659043927 | |
f1 = 0.6293346582 # useless. longer than allowed data-points can cover. | |
# Leaving out higher frequencies =, at decent sample rates it renders most 0s. | |
frequencies = [f2, f3, f4, f5, f6, f7] #f1, f8, f9, f10, f11] | |
# Periods in Seconds | |
p6 = 0.0209040092 | |
p5 = 0.0338233974 | |
p4 = 0.0885508041 | |
p3 = 0.1432782107 | |
p2 = 0.3751072254 | |
p1 = 1.5889797057 | |
longestPeriod = p2 | |
# Where every Brain/Schumann frequency meet again after zero. For a clean Fundamental cycle. | |
# Seconds | |
# FundamentalPeriod = 206.3491206 # Supposedly ideal to restart cycles from Zero. by file too large | |
# Sample rate optimized to fit My coil charging time to one datapoint duration. | |
# That way, the opening of the MOSFET switch happens right after coild is full, and no current | |
# is wated to GND. | |
sampling_rate = 8192 / (2 * longestPeriod) # in Hz ~2x max freq used | |
# (8192 = sampling_rate * FundamentalPeriod) To match one cycle to Junctek's 8192 data-points window | |
FundamentalPeriod = 2 * longestPeriod | |
num_points = int(FundamentalPeriod * sampling_rate) | |
# Generate time values | |
time_values = [i / sampling_rate for i in range(num_points)] | |
waveform = [] | |
lastImpulseTime = -1 | |
# Returns 1 unless a frequency completed a cycle in currentTime, where it returns a negative value | |
# representing the index in the frequencies list, | |
# meaning an Impulse should be produced. | |
# All Frequencies "Complete a cycle" on time zero. | |
# spacing ensures the given amount of time is preserved between impulses regardless of frequencies. | |
def getLevel(currentTime: float, previousTime: float, spacing: float) -> float: | |
global lastImpulseTime | |
if (currentTime - lastImpulseTime) < spacing: | |
# Avoid impulses, Coil re-charging. | |
return 0.1 | |
for i in range(len(frequencies)): | |
f = frequencies[i] | |
period = 1.0 / f | |
currentMod = currentTime % period | |
previousMod = previousTime % period | |
if currentMod <= previousMod: | |
# A cycle completed send them impulses! | |
level = - (i / (len(frequencies) - 1)) | |
lastImpulseTime = currentTime | |
return level | |
# No one completed a cycle. | |
return 0.1 | |
# Wave form is pulse: HIGH unless any used freq is starting a cycle. | |
# This is intended to create an impulse at the start of every cycle. | |
# Impulse frequency is 1MHz. so need to wait min 10X to charge coil. | |
# That is guarantee min UP time of 10uS (microSeconds) between LOWs. | |
def makeWave(): | |
global waveform, num_points | |
# return to one right after an impulse adds extra elements on both time_values & waveform | |
# which can have JDS8000 confused when no constant increments in time interval. | |
# safe side is to ensure spacing > timeIncrements | |
spacing = 1 / (sampling_rate - 1) | |
# waveform admits 0 or 1 values. | |
waveform = numpy.empty(num_points, float) | |
for i in range(num_points): | |
level = getLevel(time_values[i], 0 if i == 0 else time_values[i - 1], spacing) | |
waveform[i] = level | |
if level < 0.1 and i > 0: | |
# charcge the coil in previous datapoint, note coil resonance Freq must be | |
# >= 10x sample_rate to allow time for charging. | |
waveform[i - 1] = 1 | |
#if level == 0 and spacing < timeIncrements: | |
# return to one right after. Adds extra elements on both time_values & waveform | |
# or maybe not, as JDS8000 might get confused when no constant increments in time interval. | |
#safe side is to ensure spacing > timeIncrements | |
makeWave() | |
print(f"waveform length {len(waveform)}") | |
print(f"time_values length {len(time_values)}") | |
maxValues = 8192 | |
# maxValues = num_points | |
# Header: | |
# Junctek csv | |
with open('waveform.csv', mode='w', newline='', encoding='us-ascii') as file: | |
writer = csv.writer(file, delimiter=';') | |
writer.writerow(['Junctek_csv']) | |
for i in range(maxValues): | |
# writer.writerow([waveform[i]]) | |
writer.writerow([f"{waveform[i]:.4f}"]) | |
print(f"waveform duration: {time_values[maxValues - 1]} Seconds") | |
print(f"waveform 'freq' for fn generator config: {1 / time_values[maxValues - 1]} Hz") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment