{"id":19832025,"url":"https://github.com/danielmartensson/jlogger-mobile","last_synced_at":"2025-09-09T23:22:17.798Z","repository":{"id":120604408,"uuid":"205921985","full_name":"DanielMartensson/JLogger-Mobile","owner":"DanielMartensson","description":"A free opensource sensor to log file IoT tool for Android/Iphone/Windows/Linux/Mac","archived":false,"fork":false,"pushed_at":"2020-10-13T16:50:41.000Z","size":133279,"stargazers_count":7,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-06T15:26:26.007Z","etag":null,"topics":["android","c","embedded-systems","gluon-mobile","ios","iot","java","javafx","logging","spring"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DanielMartensson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-02T19:19:08.000Z","updated_at":"2024-08-21T09:44:10.000Z","dependencies_parsed_at":null,"dependency_job_id":"1e3f0ea8-5640-4581-9b30-8a5932ec8ef7","html_url":"https://github.com/DanielMartensson/JLogger-Mobile","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DanielMartensson%2FJLogger-Mobile","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DanielMartensson%2FJLogger-Mobile/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DanielMartensson%2FJLogger-Mobile/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DanielMartensson%2FJLogger-Mobile/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DanielMartensson","download_url":"https://codeload.github.com/DanielMartensson/JLogger-Mobile/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251907049,"owners_count":21663207,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","c","embedded-systems","gluon-mobile","ios","iot","java","javafx","logging","spring"],"created_at":"2024-11-12T11:36:00.471Z","updated_at":"2025-08-28T22:13:11.759Z","avatar_url":"https://github.com/DanielMartensson.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JLogger\n\nThis is an IoT tool that can sample values and control PWM signals over the internet. Today IoT is becoming more and more usefull thanks to the speed of the internet. This IoT tool make it easier for you to sample measurement data, while control e.g. hydraulic cylinder or a DC motor. Very unique thing to use. \n\nThis software is made by using:\n```\n* GluonHQ JavaFX 8 for Android/iOS/Windows/OSX/Linux\n* Spring Boot with Spring security\n* JserialComm for communicatation with a microcontroller\n* Apache Client\n* MySQL Server \n* Scene Builder 8\n```\n\n## How does it looks like?\n\nFirst you can select a file by either create a new one from the pen icon, or select a previous one.\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/LogFiles.png)\n\nThen you can try to login with your password and username. Also if you have admin rights, then you can create, edit and delete user.\nEverybody can view who is online and what device they are using.\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/Login.png)\n\nThen before you starting to sample, then you might want to set some calibration and legends to the plot. The calibration follows the y = kx + m formula, where the k is the slope and m is the bias and x is the ADC value from the microcontroller and y is our sampled value. In this case, I say that all legends are indexing from 0 to 5. \n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/Configurations.png)\n\nThen I starting to sample. To the right you can se a panel with sliders. Here I can control the PWM output for the microcontroller.\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/Logging.png)\n\nAnd this is how my output looks like. If I only select few legends, the column width is going to be smaller. So this software is very dynamical and does not use unnecessary legends that are not being used.\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/Result.png)\n\nIf you not planning to use JLogger as a logging tool, you can use it to turn on relays, lamps, pumps etc, or have it as a home equipment to light up the house before you comming home. This IoT-tool have 27 different digital outputs to use and also memory saving so you won't forget which button have been activated before.\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/Digitals.png)\n\n## Microcrontroller connection\n\nThis software is using a microcontroller. I have selected the Nucleo board STM32F446RE. \n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/Microcontroller.jpg)\n\nThe pinmap looks like this.\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/Pinmap.png)\n\nAnd where are the pins I have used. Notice that there is a Dither PWM pin too. That pin works that it have a constant PWM frequency. Very usefull for hydraulical propotional valves to make the main spool in a floating point all the time = reduce friction. But the PWM dither pin can serves for a simple cheap DC motor as well.\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/CPU.png)\n\n## Example\n\nHere I put a LED lamp to the PWM output PA8 and a potentiometer to the analog input A0.\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/Setup.jpg)\n\nAnd here is the real time logging display. I have only select one legend, therefore one slider will only be avaiable to use and only one measurement column in the log file.\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/SetupLog.png)\n\nHere is when I have connection from my Android smartphone and I control PWM and digital outputs at the same time, without they affecting  each other.\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/Online.jpg)\n\nI also tried to implement JLoggerServer onto a Raspberry Pi Zero W and it works! Also I used MariaDB instead of MySQL and I didn't even need to change any database configurations at all. Nothing. Just boot it and run. \n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/CompleteSystem.jpg)\n\nLogin from my phone\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/AndroidLogin.png)\n\nReal time sampling from my phone when JLoggerServer is applied onto Raspberry Pi Zero W\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/AndroidLogging.png)\n\nDigials works as well\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/AndroidDigitals.png)\n\nAnd connect it to PuTTY SSH Client works too\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/Putty.png)\n\nTo make JLoggerServer bootable inside a Raspbery. Just paste this code right above `exit 0` in `/etc/rc.local`\nAlso, you need to implement JLoggerServer as well.\n\n![a](https://raw.githubusercontent.com/DanielMartensson/JLogger/master/Pictures/BootRaspberry.png)\n\nJust follow this [manual](https://www.raspberrypi.org/documentation/linux/usage/rc-local.md) about make a program bootable at startup onto a Raspberry Pi/Ubuntu/Debian etc.\n\n\n## How do I use this software?\n\nStep 1: Install MySQL and create a user that have granted rights to create tables and databases\n\nStep 2: Edit the application.properties in the JLoggerServer folder. Here you place the user and password of the MySQL user you just have created. Also the server is configured at port 80. That means you can connect the server from your local area IP address e.g 192.168.x.x. Set port to 8080 if you want to have localhost IP to connect with.\n\nStep 3 (optional): Edit the InitialStartUp.java class in JLoggerServer and change the admin name and admin password to your admin name admin password. Else you can just login with JLogger application with the \"admin\" and password \"admin\" and then edit the admin user because you are admin. \n\nStep 4: Install OpenJDK 8 from AdoptOpenJDK and OpenJFX 8. Not OpenJFX 11. Current Java version for mobile GluonHQ is Java 8, but I will update it when GluonHQ releases support for OpenJDK 11. \n\nStep 5: Burn the JLoggerDevice project to a STM32F446RE Nucleo board. I have been using Atollic TrueStudio for this. Use CubeMX if you want to edit the pinout. JLoggerDevice is using DMA on RX-USB and ADC which makes it easier to send values to it and recive ADC values. \n\nStep 6: Start the JLoggerServer with \n```\n./gradlew bootRun // For Linux\ngradlew bootRun // For Windows\n```\n\nStep 7: Start the JLogger with\n```\n./gradlew run // For Linux\ngradlew run // For Windows\n```\nOr you can just download the Android APK file from [here](https://github.com/DanielMartensson/JLogger/tree/master/JLogger/JLoggerApp/build/javafxports/android)\n\nStep 8(optional): Create a [mobile application](https://docs.gluonhq.com/getting-started/#introduction) of JLogger at here if you want to modify.\n\n\n## How can I configure the JLoggerDevice?\n\nFirst you need to use Atollic TrueStudio to import the project. \nThen you need to use the CubeMX to change the inputs and clock configurations. You don't need to use PWM if you don't want.\nIn the main.c file, you can change where what you want to do. Example if you want to replace the PWM with SPI or something.\n\n```\n/*\n * When we get our message, in this case it will be sizeof(RXData)/sizeof(RXData[0]) bytes of slider inputs.\n * This method will be called\n */\nvoid HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {\n\n\t// Check if we are going to ONLY set PWM's(0) or set digitals(1). Last RXData have the send state element\n\tuint8_t send_state = RXData[sizeof(RXData)/sizeof(RXData[0]) - 1];\n\tif(send_state == 0){\n\t\t// Set PWM counters period by convert short -\u003e byte\n\t\thtim1.Instance-\u003eCCR1 = (uint32_t) ((RXData[0] \u003c\u003c 8) | RXData[1]);\n\t\thtim1.Instance-\u003eCCR2 = (uint32_t) ((RXData[2] \u003c\u003c 8) | RXData[3]);\n\t\thtim1.Instance-\u003eCCR3 = (uint32_t) ((RXData[4] \u003c\u003c 8) | RXData[5]);\n\t\thtim1.Instance-\u003eCCR4 = (uint32_t) ((RXData[6] \u003c\u003c 8) | RXData[7]);\n\t\thtim2.Instance-\u003eCCR1 = (uint32_t) ((RXData[8] \u003c\u003c 8) | RXData[9]);\n\t\thtim2.Instance-\u003eCCR2 = (uint32_t) ((RXData[10] \u003c\u003c 8) | RXData[11]);\n\t}else if(send_state == 1){\n\t\t// For digitals only - We start at index 13, which is position 12\n\t\tfor(uint8_t i = 12; i \u003c sizeof(RXData)/sizeof(RXData[0]); i++){\n\t\t\tif(i == 12){ \t   // Digital 0\n\t\t\t\tHAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, RXData[i]); //RXData[i] = One or Zero\n\t\t\t}else if(i == 13){ // Digital 1\n\t\t\t\tHAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, RXData[i]);\n\t\t\t}else if(i == 14){ // Digital 2\n\t\t\t\tHAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, RXData[i]);\n\t\t\t}else if(i == 15){ // Digital 3\n\t\t\t\tHAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, RXData[i]);\n\t\t\t}else if(i == 16){ // Digital 4\n\t\t\t\tHAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, RXData[i]);\n\t\t\t}else if(i == 17){ // Digital 5\n\t\t\t\tHAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, RXData[i]);\n\t\t\t}else if(i == 18){ // Digital 6\n\t\t\t\tHAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, RXData[i]);\n\t\t\t}else if(i == 19){ // Digital 7\n\t\t\t\tHAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, RXData[i]);\n\t\t\t}else if(i == 20){ // Digital 8\n\t\t\t\tHAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, RXData[i]);\n\t\t\t}else if(i == 21){ // Digital 9\n\t\t\t\tHAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, RXData[i]);\n\t\t\t}else if(i == 22){ // Digital 10\n\t\t\t\tHAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, RXData[i]);\n\t\t\t}else if(i == 23){ // Digital 11\n\t\t\t\tHAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, RXData[i]);\n\t\t\t}else if(i == 24){ // Digital 12\n\t\t\t\tHAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, RXData[i]);\n\t\t\t}else if(i == 25){ // Digital 13\n\t\t\t\tHAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, RXData[i]);\n\t\t\t}else if(i == 26){ // Digital 14\n\t\t\t\tHAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, RXData[i]);\n\t\t\t}else if(i == 27){ // Digital 15\n\t\t\t\tHAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, RXData[i]);\n\t\t\t}else if(i == 28){ // Digital 16\n\t\t\t\tHAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, RXData[i]);\n\t\t\t}else if(i == 29){ // Digital 17\n\t\t\t\tHAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, RXData[i]);\n\t\t\t}else if(i == 30){ // Digital 18\n\t\t\t\tHAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, RXData[i]);\n\t\t\t}else if(i == 31){ // Digital 19\n\t\t\t\tHAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, RXData[i]);\n\t\t\t}else if(i == 32){ // Digital 20\n\t\t\t\tHAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, RXData[i]);\n\t\t\t}else if(i == 33){ // Digital 21\n\t\t\t\tHAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, RXData[i]);\n\t\t\t}else if(i == 34){ // Digital 22\n\t\t\t\tHAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, RXData[i]);\n\t\t\t}else if(i == 35){ // Digital 23\n\t\t\t\tHAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, RXData[i]);\n\t\t\t}else if(i == 36){ // Digital 24\n\t\t\t\tHAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, RXData[i]);\n\t\t\t}else if(i == 37){ // Digital 25\n\t\t\t\tHAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, RXData[i]);\n\t\t\t}else if(i == 38){ // Digital 26\n\t\t\t\tHAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, RXData[i]);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Convert ADC values to\n\tTXData[0] = (uint8_t) (ADCValues[0] \u003e\u003e 8);\n\tTXData[1] = (uint8_t) (ADCValues[0] \u0026 0xFF);\n\tTXData[2] = (uint8_t) (ADCValues[1] \u003e\u003e 8);\n\tTXData[3] = (uint8_t) (ADCValues[1] \u0026 0xFF);\n\tTXData[4] = (uint8_t) (ADCValues[2] \u003e\u003e 8);\n\tTXData[5] = (uint8_t) (ADCValues[2] \u0026 0xFF);\n\tTXData[6] = (uint8_t) (ADCValues[3] \u003e\u003e 8);\n\tTXData[7] = (uint8_t) (ADCValues[3] \u0026 0xFF);\n\tTXData[8] = (uint8_t) (ADCValues[4] \u003e\u003e 8);\n\tTXData[9] = (uint8_t) (ADCValues[4] \u0026 0xFF);\n\tTXData[10] = (uint8_t) (ADCValues[5] \u003e\u003e 8);\n\tTXData[11] = (uint8_t) (ADCValues[5] \u0026 0xFF);\n\n\t// Send data to JLoggerServer in about 5 milliseconds\n\tHAL_UART_Transmit(\u0026huart2, TXData, sizeof(TXData)/sizeof(TXData[0]), 5);\n\n\t// Listen for a new receive\n\tHAL_UART_Receive_DMA(\u0026huart2, RXData, sizeof(RXData)/sizeof(RXData[0]));\n\n}\n```\n\n## Troubleshooting\n\nPossible trouble number 1:\n\nIf you don't get any logging values, but still connected. That means you don't send any values to the microcontroller or the microcontroller sends back to JLoggerServer, but the server don't understand. Remember, JLogger have HTTP blocking call. If the server don't answer, then the plot is going to stay still. Re-boot the server. To find the issue, have a look at PlotMeasurements.java in JLogger and DeviceController.java in JLoggerServer. They two are working together. If one stops, then the other stops as well. Most of the case, the while loop inside DeviceController.java just loops and never stops because the jSericalComm library don't read any incomming bytes. I'm working hard to make sure that this is happening. I have eliminate lots of bugs that cause the JLoggerServer won't talk to JLoggerDevice\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielmartensson%2Fjlogger-mobile","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielmartensson%2Fjlogger-mobile","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielmartensson%2Fjlogger-mobile/lists"}